AngularJS使用指令($ compile)动态创建元素并使用单例服务

时间:2015-02-11 10:23:13

标签: angularjs angularjs-directive angular-ui

我目前遇到angularJS的问题(或者我对它的理解 - 我来自C#背景)

我正在开发一个项目,该项目需要动态创建元素(从被拖放到页面上的结果中克隆)。一旦这些元素被删除,我希望它们能够被双击并出现一个模态。我给他们一个自定义指令(openmodal),然后通过角度编译服务运行它们。

这一切都很有效......

但是我需要它们才能访问服务(我有一个服务作为对象列表的代理),但是在通过$ compile服务运行后,它们无法访问相同的对象。我正在使用angular.injector方法来获取当前角度应用程序的编译服务,所以我无法理解为什么它不使用相同的服务实例(当上面的元素运行时会创建一个新的服务实例) $编译)。

我确信在理解它/范围如何工作方面存在问题。但是我发现这很难搜索,因为在声明一个指令(包含编译和链接函数)时也使用了“compile”这个词,而且它们是最常出现的链接。

这是一个plunk来证明我的问题。如果单击“添加数字”按钮几次(两个指令将显示与使用相同服务时相同的数字),但是在单击“创建指令”并单击“单击以显示模态”后,模式将显示数组长度为0。

我很确定这与我从javascript创建模态的方式有关。

function CreateModalDirective() {
      var compileService = angular.injector(['ng', 'numbersApp']).get('$compile');
      var scope = angular.element("#divForModal").scope();
      console.log(scope);
      var element = '<div id="theModalContainer" openmodal ng-click="OpenMyModal()">Click to show the modal</div>';
      var linkFn = compileService(element);
      var content = linkFn(scope);
      angular.element('#' + 'divForModal').append(content);
    }

“FirstController”和“SecondController”只是证明他们正在使用相同的服务,“ModalController”上的randomId参数只是表明我能够通过一个数字传递给控制器​​。

但是,如果从“纯JS函数”执行此操作是不可能的,那么我可能必须考虑重组以实现此功能 - 再次指针会很棒!!

提前致谢:)

2 个答案:

答案 0 :(得分:0)

从我发现的问题是$modal.open功能正在创建全新的应用程序,当你有新的应用程序时,你也有新的服务实例。这就是为什么我这么认为的原因。当我console.log测试控制器中的rootScope,openmodal指令的链接函数和CreateModalDirective函数时,它们都打印出相同的rootScope,但是在您通过的控制器中记录rootScope到$modal.open函数提供不同的 rootScope,并且由于一个角度应用只能有一个rootScope,这意味着我们有两个不同的应用,因此您无法看到服务结果,因为这两个是不同的同一服务的实例。这是一个经过修改的plnkr,显示了我所说的内容。

答案 1 :(得分:0)

是的,在我第四天与这个问题搏斗之后,我已经弄清楚发生了什么。

正如@getOffMyLawn所说,模态控制器正在使用一个全新的$ rootScope。 然而,从创建新应用程序的angular-ui-bootstrap开始,它不是$ modal.open函数。 相反,这是我使用angular.injector(['ng', 'appNameHere'])

检索(或认为我正在检索)注射器的方式

阅读the docs(稍微仔细一点)后,我似乎没有使用上面的代码为我的应用程序检索注入器,而是创建了一个全新的应用程序 - 然后创建了自己的实例arrayNumbers服务。

因此,要为我的应用程序检索注入器,代码如下所示: //使用jQuery选择器(仅当jQuery已包含在页面中时)

angular.element('#idOfMyAppElement').injector();

现在检索我的应用程序的注入器,我可以继续使用编译服务,它的arrayNumbers服务实例将被注入ModalController - 所以它们都链接起来。

现在,函数CreateModalDirective()的工作版本的完整代码为:

function CreateModalDirective(){
    var $injector = angular.element('#theApp').injector();
    var element = '<div id="theModalContainer" openmodal ng-click="OpenMyModal()">Click here for modal!</div>';
    $injector.invoke(function($rootScope, $compile){
        angular.element('#' + 'divForModal').append($compile(element)($rootScope));
    });
}