【问题标题】:Angular directive not working if loaded with RequireJS如果加载了 RequireJS,Angular 指令不起作用
【发布时间】:2017-01-11 11:04:41
【问题描述】:

我有一个指令在不使用 RequireJS 时可以正常工作,我正在尝试将它迁移到基于 RequireJS 的应用程序中。

该指令包装了一个 Angular UI 模态,并使用transclude 填充模态元素(模态元素在声明该指令的控制器中定义)。问题是,如果使用 RequireJS 加载,模式不会显示任何元素(即它是空的)。

This is the plunk 正确工作的指令没有 RequireJS。您将看到一个填充了元素的模式。

This is the plunk 加载 with RequireJS 的指令。你会看到模态框是空的。

模态框显示为空时不会抛出任何错误,所以我不确定如何解决这个问题。任何帮助将不胜感激。

这是指令:

define(['app','uiBootstrap'], function (app) {

'use strict';
app.directive("theModal", function($timeout,$uibModal) {
          return {
            restrict: "AE",        
            scope: {              
                control: '='
            },
            transclude: true,
            link: function (scope, element, attrs, ctrl, transclude) {

              scope.control = scope.control || {}

                scope.control.openModal = function () {

                var instance = $uibModal.open({
                      animation: false,
                      scope: scope,
                      windowClass: 'the-modal',
                      template: '<div>in the template</div><div class="content"></div>',
                      appendTo: element
                });

                $timeout(function (){
                     transclude(scope.$parent, function(clonedContent){
                       element.find('.content').append(clonedContent);  
                     })
                },10);

                };

            }
          }
    });
});

这就是我调用它的方式:

<div ng-controller="ctl">

    <button ng-click="open()">open it!</button>

    <div the-modal control="modalCtl">
        <p>some text</p>
        <input type="text" ng-model="input1" />
    </div>

</div>

【问题讨论】:

  • 在我看来,RequireJS 不适合 Angular JS。基本上,RequireJS 允许您仅在需要时加载资源。但问题是,Angular 应用程序在引导时需要它的所有服务、控制器、指令……。在您的情况下,您在使用 RequireJS 测试您的应用程序时不会看到任何错误,因为当 Angular 编译 HTML 模板时,它只是忽略了 'the-modal' 指令,因为它对您的 Angular 应用程序是未知的。

标签: angularjs angularjs-directive angular-ui-router requirejs


【解决方案1】:

问题是你有循环依赖。该应用程序需要您的模态模块才能正确显示内容,但您的模态指令需要该应用程序。解决方案是将模态指令加载到单独的模块中。

为 Modal 定义一个单独的 Angular 模块

// contents of modal.js (remove app dependency)
define(['uiBootstrap'], function () {
    'use strict';
    var mod = angular.module('modal', ['ui.bootstrap']);
    mod.directive("theModal", function($timeout, $uibModal) {
        return {
            restrict: "AE",        
            scope: {              
                control: '='
            },
            transclude: true,
            link: function (scope, element, attrs, ctrl, transclude){
              // removed code for brevity
            }
        }
    });
    mod.directive("theButton", function($timeout) {
        return {
            restrict: "AE",        
            scope: {              
                control: '='
            },
            transclude: true,
            link: function (scope, element, attrs, ctrl, transclude){
              // removed code for brevity
            }
        }
    });
    return mod;
});

让应用依赖 Modal

// contents of app.js
define([
    'angular',
    'uiBootstrap',
    'uiRouter',
    'modal'         // <--- the modal.js directive
], function (angular) {
    'use strict';
     return angular.module('app', ['ui.bootstrap','ui.router', 'modal']); // <--- also add it here
});

【讨论】:

  • 我的应用程序中有大量指令,我无法为每个指令定义一个模块。
  • 您不必这样做。您可以将它们全部添加到 modal.js。只需将其重命名为合理的名称即可。
  • 单个源文件中有几十个指令?
  • 顺便说一句,您的解决方案似乎不起作用,请参阅此 plunk:plnkr.co/edit/x9JvywJq772BQaQziApz?p=preview
  • 问题不在于解决方案。它与您的styles.css 中的css 一起使用。试试这个:plnkr.co/edit/VN2BmWRKVkw8Ixul2bml?p=preview 另外,我不一定建议您将所有指令包含在一个文件中,这只是一个选项。这取决于您的用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-06
  • 2018-12-17
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
相关资源
最近更新 更多