绑定输出上的angularjs指令

时间:2015-06-25 10:55:41

标签: angularjs angularjs-directive

我有这样的事情:

.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

我怎样才能解决这个问题? (我可以在指令范围内传递变量,但我认为必须有另一种方式)。

编辑:控制器在那里并按预期工作。问题与此无关。我没有用它来缩短帖子。

4 个答案:

答案 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. 
    }     

参考https://docs.angularjs.org/guide/directive

答案 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: '*'});