如何创建现有指令的专用版本?

时间:2014-03-14 08:53:32

标签: javascript angularjs

我的计划是创建一个ngOptions指令的专用版本,该指令可以从外部JSON源获取select个选项。我的计划是将一些ngOptions指令(基础)注入我的指令(专业化)。

angular.module('App.directives')
  .directive ("selectDatasource", function ($http, ngOptions) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            scope.dataSource = {};
            attrs.ngOptions = "k as v for (k,v) in dataSource";
            ngOptions.link (scope.element, attrs);
            $http.get(attrs).success(function(r) { scope.dataSource = r; });
        }
    };
});

然后您可以按如下方式使用它:

<select name="myOption" select-datasource="http://mysite/datasource"/>

然而,ngOptions无法注入,我无法看到如何注入指令。我不确定这是最好的方法。如果不是,那么对于专门化内置指令之一的一般条款有什么好方法呢?

2 个答案:

答案 0 :(得分:1)

请勿从select中删除ng-options。而是编写新的指令,从外部源获取数据并设置范围变量,然后由ng-options使用。像这样:

//template
<select ng-model="myModel.myValue" ng-options="k as v for (k,v) in dataSource" select-data-source="http://mysite/datasource/"></select>

//directive
module.directive('selectDataSource', function($http) {
  return {
    link: function($scope, $element, $attrs) {
      var url = $attrs.selectDataSource;
      $http.get(url).success(function(response) {
        $scope.dataSource = response;
      });
    }
  }
})

答案 1 :(得分:1)

您可以执行以下操作:

app.directive('selectDatasource', ['Loader', function (Loader) {
  return {
    scope: true,
    compile: function (tElement, attr) {
      attr.ngOptions = 'v.value as v.label for v in values';

      return function link(scope) {
        Loader.load(attr.selectDatasource).then(function (response) {
          scope.values = response;
        });
      };
    }
  };
}]);

虽然由于ngOptions的预定义格式,你会失去很多灵活性。因此,最好使用类似的东西:

app.directive('datasource', ['Loader', function (Loader) {
  return function (scope, element, attr) {
    // add to scope
    scope[attr.datasourceTarget] = [];

    // observer changes
    attr.$observe('datasource', function (nv, ov) {
      if (nv !== ov) {
        Loader.load(nv).then(function (response) {
          scope[attr.datasourceTarget] = response;
        });
      }
    });
  };
}]);

使用:

<select
  data-ng-model="test2"
  data-datasource="http://mysite/datasource"
  data-datasource-target="values"
  data-ng-options="v.value as v.label for v in values"
></select>

演示:

http://jsbin.com/rukemaha/4/