返回

时间:2016-01-06 18:16:49

标签: angularjs

我需要在输入指令返回之前访问范围变量。

我有一个指令,它返回一个带有每个卡车选项的选择元素。

<tc-vehicle-select label="Truck" selected="activeDailyLog.truck"></tc-vehicle-select>

我需要使用指令中的选定值将selected标记放在相应的选项元素上。

.directive('tcVehicleSelect', function(localStorageService) {
  /* Get a list of trucks for the organization and populate a select element for
     the user to choose the appropriate truck.
  */

  var trucks = localStorageService.get('trucks');
  var truckHtml;

  for (var i = 0; i < trucks.length; i++) {
    var truck = trucks[i];
    var injectText;

    if(truck.description){
      injectText = truck.description
    }else{
      injectText = 'truck ' + truck.id
    }

    truckHtml += '<option value="' + truck.id + '">' + injectText + '</option>'
  }

  return {
      scope: {
        label: '@',
        active: '@'
      },
      replace: true,
      template: '<label class="item item-input item-select">' +
                '<div class="input-label">{{label}}</div>' +
                '<select ng-model="timeLog.truck"><option value="">None</option>' + truckHtml +
                '</select></label>'
  };
});

除了我在正确的元素上设置selected属性之外,我已经完成了该指令的所有工作。如果我可以访问传入的selected变量,我可以通过插入truckHtml来实现,但我还没有找到使用它的示例 - 只使用了以下变量块中的变量。

有什么想法吗?

更新:还想澄清HTML中的activeDailyLog.truck是否具有我正在寻找的正确值。

2 个答案:

答案 0 :(得分:1)

  1. 将指令的代码放在link函数中是有意义的。

  2. 要在指令中检索传递的范围变量,请使用=对同一对象进行双向绑定。

  3. 代码:

    .directive('tcVehicleSelect', function(localStorageService) {
      /* Get a list of trucks for the organization and populate a select element for
         the user to choose the appropriate truck.
      */
      return {
          scope: {
            selected: '='
          },
          replace: true,
          template: '<label class="item item-input item-select">' +
                    '<div class="input-label">{{label}}</div>' +
                    '<select ng-model="timeLog.truck"><option value="">None</option>' + truckHtml +
                    '</select></label>',
          link: function(scope, elem, attrs) {
            var trucks = localStorageService.get('trucks');
            trucks.forEach(function(truck) {
              var injectText;
              if(truck.description){
                injectText = truck.description
              } else {
                injectText = 'truck ' + truck.id
              }
    
              truckHtml += '<option value="' + truck.id + '">' + injectText + '</option>'
            }
    
            // Access scope.selected here //
            console.log(scope.selected);  
          }
      };
    });
    
    1. 也替换为Array.forEach()方法,因为它在这种情况下似乎更相关!

答案 1 :(得分:0)

在内部,指令与工厂之间的差异很小。这里最重要的是指令被缓存 - 你的代码只运行一次,而且每次需要使用该指令时,angular将继续重用它的返回值。

话虽如此,你不能在指令声明体内访问范围 - 如果可能的话,它将是第一个指令的范围,其结果将被缓存并用于所有其他地方,你将使用相同的指令。

我确实喜欢在返回之前构建选项的想法,假设您确定它在应用程序生命周期中不会改变(因为它将为您节省一些不必要的绑定)。但是,它通常不是真的,所以我宁愿将整个逻辑移动到编译甚至链接函数中:

.directive('tcVehicleSelect', function(localStorageService) {

  return {
      scope: {
        label: '@',
        active: '@'
      },
      replace: true,
      template: '<label class="item item-input item-select">' +
                '<div class="input-label">{{label}}</div>' +
                '<select ng-model="timeLog.truck"><option value="">None</option>'
                '</select></label>',
      link: function(scope, element) {
              var trucks = localStorageService.get('trucks'),
                  select = element.find('select');
                  option;
              trucks.forEach(function(truck) {
                option = angular.element('<option></option>');
                option.attr('value', truck.id);
                option.html(truck.description || "truck" + truck.id);
                if (truck.id === scope.selected.id) {                  
                  option.attribute('selected', 'selected');
                }
                select.append(option);
             });
     }
  };
});