如果我多次使用我的指令,属性总是采用最后指定的值

时间:2016-02-28 21:06:12

标签: angularjs angularjs-directive

下面我一个接一个地使用我的自定义指令type-ahead-custom

第一次type-ahead-custom="maps" 第二次type-ahead-custom="maps1"

如果我在我的指令中访问属性type-ahead-custom,它总是返回" maps1" ..我该如何解决这个问题?

以下是plunker:https://plnkr.co/edit/hXlNJKboSlA2lAvRqYF1

<form class="form-horizontal" ng-controller="myCtrl" >
  <div class="form-group">
    <div>
      <label for="account" class="col-sm-2 col-md-2 control-label customize-label ">Typeahead 1</label>
      <div class="col-sm-8">
        <div class="inner-addon right-addon">

          <input type="text" ng-model="selectedOptions.planes" uib-typeahead="plane as plane.formatted_address for plane in search($viewValue)" type-ahead-custom="maps" typeahead-loading="loadingdata" typeahead-no-results="noResults" class="form-control ng-valid ng-dirty ng-valid-parse ng-touched" aria-autocomplete="list" aria-expanded="false" aria-owns="typeahead-4-8758" />
        </div>
      </div>
    </div>
  </div>

        <div class="form-group">
    <div>
      <label for="account" class="col-sm-2 col-md-2 control-label customize-label ">Typeahead 2</label>
      <div class="col-sm-8">
        <div class="inner-addon right-addon">

          <input type="text" ng-model="selectedOptions.plants" uib-typeahead="plane as plane.formatted_address for plane in search($viewValue)" type-ahead-custom="maps1" typeahead-loading="loadingdata" typeahead-no-results="noResults" class="form-control ng-valid ng-dirty ng-valid-parse ng-touched" aria-autocomplete="list" aria-expanded="false" aria-owns="typeahead-4-8758" />
        </div>
      </div>
    </div>
  </div>
</form>

//代码在这里

var exampleApp = angular.module('exampleApp', ['ui.bootstrap']);

exampleApp.directive('typeAheadCustom', function($http, $q) {
return {
    link: function($scope, $element, $attributes) {


        $scope.search = function(newValue) {

           console.log($attributes.typeAheadCustom);
         var dfr = $q.defer();
         $http.get('//maps.googleapis.com/maps/api/geocode/json', {
             params: {
                 address: newValue,
                 sensor: false
                 }
           }).success(function(data) {

              dfr.resolve(data.results);

          });

          return dfr.promise;
        };
    }
}
});

exampleApp.controller('myCtrl', function($http,$scope) {
  $scope.selectedOptions = {};
});

2 个答案:

答案 0 :(得分:1)

问题是你没有为你的指令创建一个新的范围,基本上他们在任何地方共享相同的范围。

因此,当您注册指令的第一个实例$scope.search时,方法会在$attributes.typeAheadCustommap的同一范围内创建。

在第二次指令执行时,它会覆盖由$scope.search实例&amp; amp;创建的旧1st directive方法。其$attributes.typeAheadCustom值为map1

这就是为什么当您致电search方法时,它始终会有最新的$attributes.typeAheadCustom值。

要解决您的问题,我建议您使用隔离范围创建指令。这意味着指令将拥有自己的新范围。因此,无论何时放置指令都不会出现这样的问题。指令将作为单独的组件,但是在同一页面上实例化它的时间。

现在您的指令范围与指令所在的页面范围不同,因此您无法访问指令内的控制器值,因为您需要使用隔离的scope: { ... }绑定内部传递所需的值。 / p>

答案 1 :(得分:0)

由于指令的实例化与其他指令共享范围,因此根据指令的属性值将函数添加到范围。

var exampleApp = angular.module('exampleApp', ['ui.bootstrap']);

exampleApp.directive('typeAheadCustom', function($http, $q) {
return {
    link: function(scope, elem, attrs) {
        //create object on scope
        scope[attrs.typeAheadCustom] = {};
        var vm = scope[attrs.typeAheadCustom];
        //put function on object 
        vm.search = function(newValue) {
            var message=attrs.typeAheadCustom +
                        '=' + newValue;
            console.log(message);
            //
            //Do more stuff
        };

    };
});

因此,不同实例的搜索功能有不同的名称。

 <input type="text" ng-model="selectedOptions.planes" 
     type-ahead-custom="maps1"
     uib-typeahead="plane as plane.formAddress for plane 
                    in maps1.search($viewValue)"
 >

 <input type="text" ng-model="selectedOptions.planes" 
     type-ahead-custom="maps2"
     uib-typeahead="plane as plane.formAddress for plane 
                    in maps2.search($viewValue)"
 >