我有这样的事情:
.controller('contr',['$scope', '$http',function($scope, $http){
$http.post(...).success(function(){
$scope.myTextVar = "some text here";
$scope.completed == true;
});
}]);
像这样的HTML代码段:
<div class="myClass" ng-if="completed == true" manipulate-header>
<p>{{myTextVar}}</p>
</div>
和指令,为简单起见,我们说它看起来像这样:
.directive('manipulateHeader',function(){
return{
restrict: 'A',
link: function(scope, elem){
console.log(angular.element(elem).find('p'));
}
}
});
manipulate-header
指令应该对<p></p>
标记内的文本进行一些操作,但是,它会在替换{{myTextVar}}
之前运行,因此会输出{{myTextVar}}
some text here
。
我怎样才能解决这个问题? (我可以在指令范围内传递变量,但我认为必须有另一种方式)。
编辑:控制器在那里并按预期工作。问题与此无关。我没有用它来缩短帖子。
答案 0 :(得分:3)
如果必须是指令
如果你试图在链接功能中进行字符串操作,那么你将会遇到糟糕的时间。链接函数在编译指令之前执行(这是链接函数的概念),因此任何绑定(ng-bind或其他)都不会在链接函数内编译。
要在编译阶段后执行代码,您应该使用控制器。但是,您无法访问控制器中的DOM(或者更确切地说,您不应该访问)。因此,逻辑解决方案是改为修改scope参数。我建议这样的事情:
angular.directive('manipulateHeader', function() {
return {
scope: {
myTextVar: '='
},
controller: function($scope, myFilter) {
// you can't use bindToController here because bindToController executes *after*
// this function
this.modifiedText = myFilter($scope.myTextVar);
},
controllerAs: 'ctrl',
// display the modified text in a template
template: '<span ng-bind="ctrl.modifiedText"></span>'
};
})
.filter('myFilter', function() {
return function(inputText) {
// do some text manipulation here
};
});
用法:
<manipulate-header myTextVar='myTextVar'></manipulate-header>
或者:
<p>{{ myTextVar | myFilter }}</p>
当然,您可以将此作为属性,但最佳做法表明具有模板的指令应该是一个元素。
以上只有当您需要这是一个指令时。否则,它几乎肯定是一个过滤器。
答案 1 :(得分:2)
如果需要从控制器更改$ scope变量,则需要隔离范围,
scope:{
myattr='@', // this will provide one way communication , you can define in your template as <p myattr="hello"><p>
message:'&', //This allows you to invoke or evaluate an expression on the parent scope of whatever the directive is inside
message:'=' // sets up a two-way binding expression between the directive's isolate scope and the parent scope.
}
答案 2 :(得分:1)
我不确定您是否定义了 $ scope.myTextVar 在正确的范围内。比如,如果你在任何控制器中定义它,那么指令应该在控制器范围内。
这是更新后的HTML
<div ng-controller ="MainController">
<div class="myClass" manipulate-header>
<p>{{myTextVar}}</p>
</div>
</div>
JS:
app.controller(&#39; MainController&#39;,[&#39; $ scope&#39;,function($ scope){
$ scope.myTextVar =&#34;这里的一些文字&#34 ;; }]);
app.directive('manipulateHerader',function(){
return{
restrict: 'A',
link: function(scope, elem){
console.log(angular.element(elem).find('p'));
}
}
});
以下是plunker
答案 3 :(得分:1)
正如@DanPantry所建议的那样 - 你很可能想要一个过滤器而不是一个指令
阅读本指南,了解如何使用过滤器 https://docs.angularjs.org/guide/filter
以下是此类过滤器的示例(来自文档)
angular.module('myStatefulFilterApp', [])
.filter('decorate', ['decoration', function(decoration) {
function decorateFilter(input) {
//This is the actual modification of text
//That's what you are looking for
return decoration.symbol + input + decoration.symbol;
}
decorateFilter.$stateful = true;
return decorateFilter;
}])
.controller('MyController', ['$scope', 'decoration', function($scope, decoration) {
$scope.greeting = 'hello';
$scope.decoration = decoration;
}])
.value('decoration', {symbol: '*'});