我正在编译并将指令与隔离范围链接起来(请注意这是手动编译和链接,原因超出了本问题的范围):
outerElement = angular.element(domElement);
$injector = outerElement.injector();
$compile = $injector.get('$compile');
getTheIsolateScopeForMyDirectiveInstance().myProperty = 'foo'; // Pseudocode. I want myProperty to be available on the scope from inside the controller constructor function.
link = $compile(angular.element('<my-directive></my-directive>'));
// IIUC, the following line will instantiate
// the controller for the directive, injecting
// the isolate scope. I want to augment the
// isolate scope that is injected *before* it
// is injected.
// The value to augment the scope resides in
// *this* execution context.
// How can I do so?
renderedElement = link(outerElement.scope());
element.append(renderedElement);
MyDirective
有一个隔离范围(我要扩充的范围),以及与之关联的控制器。
控制器MyDirectiveController
利用注入器注入其隔离范围。
MyDirectiveController.$inject = [ '$scope' ];
我希望在将注入到MyDirectiveController
的实例之前扩充隔离范围,其值只能在上面代码的执行上下文中的运行时知道
我该怎么做?
MyDirective
function MyDirective() {
return {
scope: {}, // I want to augment this before it is injected into MyDirectiveController
restrict: 'E',
template: template,
controller: 'myDirectiveController',
controllerAs: 'ctrl',
replace: true,
};
}
MyDirectiveController
function MyDirectiveController($scope) {
console.log($scope.myProperty); // Should be 'foo'.
}
MyDirectiveController.$inject = ['$scope'];
如果这是不可能的,是否有其他方式可以使控制器可以使用特定于实例的信息和/或隔离指令的范围?
我现在能想到的唯一方法是扩充上面提供给link(outerElement.scope())
的范围,然后在指令的隔离范围上定义=
属性。
修改
这就是我现在正在做的事情,myProperty
值最终会出现在控制器的隔离范围的父级上:
var isolate = outerElement.scope().$new(true);
isolate.myProperty = 'foo';
renderedElement = link(isolate);
element.append(renderedElement);
鉴于此,实例化MyDirectiveController
时:
function MyDirectiveController($scope) {
$scope.myProperty; // undefined
$scope.$parent.myProperty; // 'foo'
}
答案 0 :(得分:2)
这里的假设
控制器MyDirectiveController利用注入器 它的隔离范围注入。
MyDirectiveController。$ inject = ['$ scope'];
我希望在将隔离范围注入到隔离范围之前对其进行扩充 MyDirectiveController的一个实例,其值只有在 运行时在上面代码的执行上下文中。
错了。 $inject只不过是注释,只有在代码缩小时才会有所作为。
在链接指令之前,你不能将任何东西“注入”隔离范围。一些丑陋的猴子修补可以解决这个问题:
var _new = scope.$new;
scope.$new = function () {
return angular.extend(_new.apply(this, arguments), {
myProperty: 'foo'
})
};
$compile(angular.element('<my-directive></my-directive>'))(scope);
scope.$new = _new;
但即使可能,它也适合编写测试而不适用于生产代码。
这里唯一直截了当的方式(以及使用隔离范围的原因)是
function MyDirective() {
return {
scope: {
myProperty: '='
},
...
};
}
和
$compile(angular.element('<my-directive my-property="myProperty"></my-directive>'))(scope);
其中scope.myProperty
等于'foo'。
答案 1 :(得分:1)
UPDATE2 :如果您需要隔离范围,请创建new scope:
var myparentscope = outerElement.scope()
var myscope = myparentscope.$new(true) // or $rootScope.$new(true, myparentscope), see true here, it isolates scope from parent.
myscope.prop = 'new prop' // define on child scope.
renderedElement = link(myscope);
element.append(renderedElement);
<强>更新强>: 代码中的最后四行:
getTheIsolateScopeForMyDirectiveInstance().myProperty = 'foo';
link = $compile(angular.element('<my-directive></my-directive>'));
renderedElement = link(outerElement.scope());
element.append(renderedElement);
应该是:
var myscope = outerElement.scope()
scope.myProperty = 'foo'
renderedElement = link(myscope);
原始回答:
.directive('myDirective',['$compile', function($compile) {
return {
link:link,
scope: {
}
}
function link(scope, element) {
scope.prop = 'new value' // new property on scope
var renderedElement = $compile('... html ...')(scope);
element.append(renderedElement);
}
})
另外
$ compile = $ injector.get(&#39; $ compile&#39;); //我认为这是实例化的 幕后与myDirective相关的控制器?
$inject.get('$compile')
是获得$compile
服务的复杂方式。如果编译服务不是(并且它不是)依赖于您的服务,您可以像通常那样使用依赖注入来指定它。
此外,我认为您需要阅读本部分关于指令生命周期中的编译和链接步骤。
编译步骤不是$compile
服务。编译步骤在应用程序的每个生命周期执行一次,将其视为使用指令的所有实例的准备。
链接步骤(前后链接)正在执行您准备好的指令,并实际将其实例化为您应用中的特定位置/范围等。
由于您需要更新范围 - 这是您要使用的链接步骤。
有关该主题的精彩视频 - https://egghead.io/lessons/angularjs-compile-pre-and-post-link