将变量的值传递给angularjs指令模板函数

时间:2013-12-28 04:02:01

标签: javascript angularjs

我正在尝试将$ scope的变量传递给指令,但它不起作用。我正在模板函数中捕获变量:

app.directive('customdir', function () {

    return {
        restrict: 'E',

        template: function(element, attrs) {
            console.log(attrs.filterby);
            switch (attrs.filterby) {
                case 'World':
                    return '<input type="checkbox">';
            }
            return '<input type="text" />';
        }
    };
});

我需要的是变量filterby的值而不是变量名本身。

Plunkr Demo

3 个答案:

答案 0 :(得分:14)

或者像这样

app.directive('customdir', function ($compile) {
  var getTemplate = function(filter) {
    switch (filter) {
      case 'World': return '<input type="checkbox" ng-model="filterby">';
      default:  return '<input type="text" ng-model="filterby" />';
    }
  }

    return {
        restrict: 'E',
        scope: {
          filterby: "="
        },
        link: function(scope, element, attrs) {
            var el = $compile(getTemplate(scope.filterby))(scope);
            element.replaceWith(el);
        }
    };
});

http://plnkr.co/edit/yPopi0mYdViElCKrQAq9?p=preview

答案 1 :(得分:9)

模板不应包含逻辑,因为模板是 view 。模板应该只包含绑定指令,以便根据范围的变化( 模型 )更新 视图 。像这样:

app.directive('customdir', function ($compile) {

    return {
        restrict: 'E',

        scope:{
          filterby:"="
        },

        link:function (scope, element) {
          scope.$watch("filterby",function(newValue){ //logic is out of template
              if (newValue == "World"){
                scope.showCheckBox = true;
              }
              else {
                scope.showCheckBox = false;
              }
          });
        },

        template: function(element, attrs) {
         //View should be passive and only listens to changes of model to update it accordingly.
            return '<input type="checkbox" ng-show="showCheckBox" / ><input type="text" ng-show="!showCheckBox"  />'; 
        }
    };
});

使用这种方法,您甚至可以在运行时更改输入,并更新视图以反映更改。

DEMO

如果您想根据某些配置决定使用哪个模板,您应该通过普通属性进行配置,不应该通过范围的属性进行访问。就像这样:

app.directive('customdir', function ($compile) {

    return {
        restrict: 'E',
        scope: {
            filterby:"=" //filterby is a separate field used for data binding
        },

        template: function(element, attrs) {
            switch (attrs.type) { //view selection configuration should be obtained from the element
                case 'checkbox':
                    return '<input type="checkbox">';
            }
            return '<input type="text" />';
        }
    };
});

通过传递正常值来配置它:

<customdir type="checkbox" filterby="name"></customdir>

DEMO

答案 2 :(得分:1)

首先,什么是template功能?它应该是link函数。其次,你错误地重载了链接函数,这里的顺序很重要,它总是scope, element, attrs。第三,在一个隔离范围内传递变量:

app.directive('customdir', function ($compile) {

    return {
        restrict: 'E',
        scope:{
          filterby:'='
        },

        link: function(scope,element, attrs) {
            console.log(scope.filterby);
            switch (scope.filterby) {
                case 'World':
                    return '<input type="checkbox">';
            }
            return '<input type="text" />';
        }
    };
});

或者如果你坚持属性那么:

 app.directive('customdir', function ($compile) {

        return {
            restrict: 'E',

            link: function(scope,element, attrs) {
                console.log(attrs.filterby);
                switch (attrs.filterby) {
                    case 'World':
                        return '<input type="checkbox">';
                }
                return '<input type="text" />';
            }
        };
    });

但在你的HTML中:

 <customdir filterby="{{name}}"></customdir>

确保首先评估变量值。最后你不应该像那样操纵DOM,事实上链接函数不会像你期望的那样呈现html。你有一个静态模板,你的链接函数将作为在模板上设置变量值的东西。