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

AngularJS dynamically creating elements with directives ($compile) and using a singleton service

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

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

这一切都很好...

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

我确定我对 it/scopes 工作原理的理解有问题。但是我发现这很难搜索,因为在声明指令时也使用了 "compile" 这个词(包含编译和 link 函数)并且它们是 link出现最多

这里 plunk 展示了我的问题。如果您单击 "Add number" 按钮几次(两个指令将显示相同的数字,因为它们使用相同的服务),但是在单击 "Create Directive" 并单击 "Click to show modal" 之后,模式会显示数组长度为 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 参数只是证明我可以通过数字传递给控制器。

但是,如果无法从 "pure JS function" 执行此操作,那么我可能不得不考虑重组以实现此功能 - 再次指出会很棒!

提前致谢:)

据我所知,问题在于 $modal.open 函数正在创建全新的应用程序,当您拥有新应用程序时,您也会拥有新的服务实例。这就是我这么认为的原因。当我 console.log 测试控制器中的 rootScope、openmodal 指令的 link 函数和 CreateModalDirective 函数时,它们都打印出相同的 rootScope,但是将 rootScope 记录在您传递给 $modal.open 函数的控制器提供 不同的 rootScope,并且由于一个 angular 应用程序只能有一个 rootScope,这意味着我们有两个不同的应用程序,因此您可以' 查看服务结果,因为这是同一服务的两个不同实例。这是经过修改的 plnkr,显示了我所说的内容。

是的,在我处理这个问题的第 4 天之后,我已经弄清楚发生了什么。

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

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

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

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

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

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

函数 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));
    });
}