具有双向值绑定和typeahead的指令

时间:2014-09-04 13:38:56

标签: angularjs

我想创建一个带有bootstrap typeahead的输入字段的指令。 像这样:

<my-input value="myCar" value-expr="car as car.name for car in cars"></my-input>

输出如下:

<input type="text" ng-model="myCar" typeahead="car as car.name for car in cars"/>

myCar和cars是父作用域的值,所以我认为必须在我的指令中选择 scope:true 才能访问这些值。我的页面上有许多my-input指令,具有不同的更改值。 我的指示:

return {
  restrict: 'E',
  scope: true,
  templateUrl: 'my-input.html',
  compile: function (tElement, tAttrs) {
      inputEl = tElement.find('input');
      inputEl.attr('typeahead', tAttrs.valueExpr);
      inputEl.attr('ng-model', tAttrs.value);
      return function (scope, element, attrs) {
          scope.changed= false;
      }
   }
}

我的问题是:如果我选择带有我的预先输入的汽车,指令范围的myCar值会改变,但父范围的myCar值不会改变。我希望你能理解我的问题。

1 个答案:

答案 0 :(得分:1)

我认为这样的事情会对你有用:

return {
    restrict : 'E',
    scope : {
        ngModel : '=',
        cars : '='
    },
    template : '<input ng-model="ngModel" typeahead="car as car.name for car in cars">',
    replace : true
};

然后您的HTML将如下所示:

<my-input ng-model="myCar" cars="cars"></my-input>

这会在您的指令与父控制器的范围变量之间创建双向绑定, cars 可能不需要双向绑定

修改

即使是更简单的解决方案,您也可以像这样完全保留范围:

return {
    restict : 'E',
    template : '<input type="text" typeahead="car as car.name for car in cars">',
    replace : true
};

然后是HTML

<my-input ng-model="myCar"></my-input>

ngModel 属性会自动将其作为属性存入模板,并保留与父控制器的绑定。

编辑 - 改变预先输入的表达式

.directive('myInput', function($compile){
    return {
        restrict : 'E',
        template : '<input type="text">'
        replace : true,
        link : function($scope,el){
            var model = el.attr('ng-model');
            var ta = el.attr('value-expr');
            return $compile($('input',el).attr('ng-model',model).attr('typeahead',ta))($scope);
        }
    };
 }) // end directive

HTML:

<my-input ng-model="myCar" value-expr="car as car.name for car in cars"></my-input>

编辑 - 更新父范围但保持指令范围

return {
    restrict : 'E',
    replace : true,
    template : '<input type="text" ng-model="value" typeahead="{{valueExpr}} | filter:$viewValue" typeahead-on-select="onSelect($item,$model,$label)" class="form-control">',
    scope : {
        value : '=',
        collection : '=',
        valueExpr : '@'
    },
    link : {
        pre :  function(scope,el){
            /*var ta = el.attr('value-expr');
            return $compile($('input',el).attr('ng-model',scope.ngModel).attr('typeahead',ta))(scope);*/
            //$compile($('input',el));
        },
        post : function(scope,el,attrs){
            scope.changed = false;
        }
    }
};

这是一个工作小提琴:http://jsfiddle.net/mikeeconroy/3mgx5f7o/3/