Angularjs - 将属性值动态附加到绑定对象。怎么样?

时间:2014-01-29 22:32:26

标签: javascript jquery angularjs binding

我试着寻找这个,但我不知道如何表达这个想法。让我试着解释一下。我仍然试图掌握指令中的整个范围。

下面的代码是同一指令的一些变体(它不是很多代码,它只是这样)

说..在我的控制器中我有这个

$scope.foo = {name: "John", color: "Green"};

我的指令看起来像这样

app.directive("miniDirective", function () {
return {
    restrict: "A",
    scope: {
        type: "=type",
        value: "@value"
    },
    template:'<div>{{content}}</div>' + 
             '<input type="text" ng-model="content">',
    link: function (scope, iElm, iAttrs) {

        switch (scope.value) {
            case "name":
                scope.content = scope.type.name; break;
            case "color":
                scope.content = scope.type.color; break;
        }
        console.log(scope.content);
    }
}

})

我想像我这样使用我的指令

    <div mini-directive
        type="foo"
        value="name">
    </div>

    <br/>

    <div mini-directive
        type="foo"
        value="color">
    </div>
  

问题1:如果我使用上面的指令,那么scope.content不会绑定回范围foo(类型属性)值。我有点理解为什么这是,   但我不知道如何实现这一目标......

然后我尝试以不同的方式做到了......这就是我被卡住的地方,,,

app.directive("miniDirective", function () {
return {
    restrict: "A",
    scope: {
        type: "=type",
        value: "@value"
    },
    template:'<div>{{type.XXXX}}</div>' + 
             '<input type="text" ng-model="type.XXXX">',
    link: function (scope, iElm, iAttrs) {

       // I WOULD LIKE TO CHANGE xxxx based on value attribute 
       // AND keep the binding working
           scope.type.xxxx;

    }
}
})

问题

有没有办法将值属性value: "@value"中的值转换为可以动态应用于scope.type.xxxx的值;其中xxxx是名称还是颜色?是否可以在不使用“切换”的情况下完成,如我在第一个示例中所做的那样,或者“if else”或检查现有值的任何条件......

OR ,,,在我使用switch的情况下,是否有办法将scope.content绑定回foo.name或foo.color依赖于属性中传递的值?

我正在尝试为此制作一个jsfiddle ......

我非常感谢你的帮助。

1 个答案:

答案 0 :(得分:2)

如果您只需要将模板绑定到外部范围对象的属性,则无需创建隔离范围。

您可以根据指令的属性轻松创建正确的表达式,如下所示:

var expression = tAttrs.type + '.' + tAttrs.value // foo.name

然后只需使用该表达式创建一个模板:

'<input ng-model="' + expression + '">' // <input ng-model="foo.name">

您可以将函数传递给指令的模板选项,然后根据需要构建模板。

这是一个吸虫:http://plnkr.co/edit/ekvPcyXeEPuebmC2mbHP?p=preview

解决方案:

app.directive("miniDirective", function () {
  return {
      restrict: "A",
      template: function(tElm,tAttrs){
       var exp = tAttrs.type + "." + tAttrs.value;
       return '<div>{{' + exp + '}}</div>' + 
              '<input type="text" ng-model="' + exp + '">';
      }
  }
})

如果您因其他原因需要创建隔离范围

  • 使用上面提到的表达式创建双向数据绑定。
  • 我使用$parse进行优化。
  • 我在评论中提到templateUrl

另一名掠夺者:http://plnkr.co/edit/zG9dbnlUjjr1KTwbVe2i?p=preview

app.directive("miniDirective", function ($parse) {
  return {
      restrict: "A",
      scope:{},
      templateUrl: "mini.html",
      compile: function(tElm, tAttrs){
        var expFn = $parse(tAttrs.type + '.' + tAttrs.value);
        return function(scope,elm,attrs){

          scope.$parent.$watch(expFn, function(val){
            scope.exp = val;
          })

          scope.$watch('exp', function(val){
            expFn.assign(scope.$parent, val)
          })

        }
      }
  }
})

以及模板:

<div> {{ exp }}</div>
<input type="text" ng-model="exp">