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

AngularJS使用指令($compile)和单例服务动态创建元素,angularjs,angularjs-directive,angular-ui,Angularjs,Angularjs Directive,Angular Ui,我目前对angularJS有问题(或者我对它的理解——我来自C#背景) 我正在从事一个需要动态创建元素的项目(从页面上拖放的结果中克隆)。一旦这些元素被删除,我希望它们能够被双击,并出现一个模态。我给它们一个自定义指令(OpenModel),然后通过angular编译服务运行它们 这一切都很好 但是,我需要它们能够访问服务(我有一个服务作为对象列表的代理),但是在通过$compile服务运行之后,它们无法访问相同的对象。我正在使用angular.injector方法获取当前angular应用程序

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

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

这一切都很好

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

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

下面是一个演示我的问题的例子。如果您多次单击“添加数字”按钮(两个指令将显示相同的数字,因为它们使用相同的服务),但是在单击“创建指令”并单击“单击以显示模式”后,模式表示数组长度为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);
    }
函数CreateModalDirective(){
var compileService=angular.injector(['ng','numbersApp']).get('$compile');
var scope=angular.element(“#divForModal”).scope();
console.log(范围);
var元素='单击以显示模式';
var linkFn=编译服务(元素);
var内容=linkFn(范围);
angular.element('#'+'divForModal').append(content);
}
“FirstController”和“SecondController”只是说明它们使用的是相同的服务,“ModalController”上的randomId参数只是说明我能够将一个数字传递给控制器

但是,如果不能从“纯JS函数”中实现这一点,那么我可能必须考虑重新构造,以实现这一功能-指针也会很好


提前感谢:)

从我发现的问题是,
$modal.open
功能正在创建全新的应用程序,当您有新的应用程序时,您也有新的服务实例。这就是为什么我这么认为。当I
console.log
测试控制器中的rootScope、openmodal指令的link函数和
CreateModalDirective
函数中的rootScope时,它们都打印出相同的rootScope,但是,在传递给
$modal.open
函数的控制器中记录rootScope会产生不同的rootScope,并且由于一个angular应用程序只能有一个rootScope,这意味着我们有两个不同的应用程序,因此您无法看到服务结果,因为这是同一服务的两个不同实例。这里有一个修改版,显示了我所说的话。

好吧,在我与这个问题进行了第四天的斗争之后,我已经知道发生了什么

正如@getOffMyLawn所说,模态控制器使用的是全新的$rootScope。 然而,创建新应用程序的不是angular ui引导中的$modal.open函数。 相反,这是我使用
angular.injector(['ng','appNameHere'])检索(或认为检索)喷油器的方式。

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

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

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

函数CreateModalDirective()的工作版本的完整代码如下:

函数CreateModalDirective(){
var$injector=angular.element('#theApp').injector();
var元素='单击此处查看模态!';
$injector.invoke(函数($rootScope,$compile){
element('#'+'divForModal').append($compile(element)($rootScope));
});
}

感谢您的关注,您的思路是正确的-它们是两个完全不同的$RootScope,但是我是罪魁祸首,因为我使用angular.injector(['ng',numbersApp')创建了一个新的应用程序-结果是您必须转到应用程序所在的元素,然后对其调用.injector()函数(请参阅我的答案)-与您检索某些元素的作用域的方式非常相似!是否有方法将作用域内的任何对象传递给编译函数而不是作用域。例如,我有$scope.myCustomVal={key1:“val1”};现在我想这样使用:$compile(elm)($scope.myCustomVal);我想设置相同的作用域,只需要呈现一个键,并且该键是动态生成的。是的,您可以在编译和添加属性之前创建一个新的作用域。例如,var myNewScope=$rootScope.$new();myNewScope.myCustomVal={key1:“val1”}$编辑(elm)(myNewScope);这将使用您刚刚创建的范围编译元素,并添加“myCustomVal”以创建新的范围,因为它很难销毁。我希望动态地创建这样的指令,以便使用$scope.myCustomVal呈现其模板。我只想呈现值为$scope.myCustomVal的模板。我
angular.element('#idOfMyAppElement').injector();
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));
    });
}