Javascript 在own指令中包装Angular.js ui引导或ui选择指令

Javascript 在own指令中包装Angular.js ui引导或ui选择指令,javascript,angularjs,Javascript,Angularjs,我正在创建一个大型Angular.JS应用程序,它使用一些第三方模块,如ui select和ui bootstrap。 为了避免重复我自己,我开始创建一些指令,这些指令正在包装,例如ui选择代码和检索/搜索数据的逻辑 目标: 目标是创建一个指令,该指令可以在模板中使用,而无需在控制器中复制代码: <tq-car-select ng-model="model.car"></tq-car-select> 我为这种选择字段创建了指令 用户界面选择的实际示例: tq-lead-

我正在创建一个大型Angular.JS应用程序,它使用一些第三方模块,如ui select和ui bootstrap。 为了避免重复我自己,我开始创建一些指令,这些指令正在包装,例如ui选择代码和检索/搜索数据的逻辑

目标: 目标是创建一个指令,该指令可以在模板中使用,而无需在控制器中复制代码:

<tq-car-select ng-model="model.car"></tq-car-select>
我为这种选择字段创建了指令

用户界面选择的实际示例

tq-lead-select.html:

<ui-select ng-model="$parent.tqModel" style="display: block">
    <ui-select-match placeholder="tippen ...">{{$select.selected.bezeichnung}}</ui-select-match>
    <ui-select-choices repeat="lead in leads | filter:{bezeichnung: $select.search}">
        <div ng-bind-html="lead.bezeichnung | highlight: $select.search"></div>
    </ui-select-choices>
</ui-select>
问题

  • 我需要独立的作用域,因为有些视图使用一个字段的多个实例
  • 我使用的是隔离范围变量tqModel,它由ui select指令的ngModel设置
  • 我希望使用ng required,而不在tqLeadSelect指令上创建tq required范围变量
问题

  • 我做得对吗?有没有更好的方法来实现我的目标
  • 您如何使用支持控制器代码定义用于检索数据和其他函数的选择字段

一种解决方案是添加一个扩展现有指令的指令

我用一个例子创建了一个Plunker:

以下代码:

HTML:

可以通过使用配置指令来简化:

<ui-select ng-model="adress.selected" tq-select></ui-select>

控制器现在是空的

指令:

app.directive("tqSelect", function($http) {

  return {
    restrict: "A", // Attribute
    require: ["uiSelect", "ngModel"],

    compile: function compile(tElement, tAttrs, transclude) {

      // Add the inner content to the element
      tElement.append('<ui-select-match placeholder="Enter an address...">{{$select.selected.formatted_address}}</ui-select-match>\
      <ui-select-choices repeat="address in addresses track by $index" refresh="refreshAddresses($select.search)" refresh-delay="0">\
        <div ng-bind-html="address.formatted_address | highlight: $select.search"></div>\
      </ui-select-choices>');

      return {
        pre: function preLink(scope, iElement, iAttrs, controller) {},
        post: function postLink(scope, iElement, iAttrs, controller) {

          // logic from controller
          scope.address = {};
          scope.refreshAddresses = function(address) {
            var params = {
              address: address,
              sensor: false
            };
            return $http.get(
              'http://maps.googleapis.com/maps/api/geocode/json', {
                params: params
              }
            ).then(function(response) {
              scope.addresses = response.data.results
            });
          };
        }
      }
    }
  }
});
app.directive(“tqSelect”),函数($http){
返回{
限制:“A”,//属性
要求:[“uiSelect”,“ngModel”],
编译:函数编译(远程通讯、tAttrs、转置){
//将内部内容添加到元素中
tElement.append(“{{$select.selected.formatted_address}”\
\
\
');
返回{
前置:功能预链接(范围、IELENT、iAttrs、控制器){},
post:功能postLink(范围、IELENT、iAttrs、控制器){
//来自控制器的逻辑
scope.address={};
scope.refreshAddresses=函数(地址){
变量参数={
地址:地址:,
传感器:错误
};
返回$http.get(
'http://maps.googleapis.com/maps/api/geocode/json', {
params:params
}
).然后(功能(响应){
scope.addresses=response.data.results
});
};
}
}
}
}
});
指令是实际棘手的部分。我在编译函数中使用了一个不平凡的逻辑。首先,我为ui select指令添加所需的标记

然后在post link函数中,我添加了通常在控制器(或link()-函数)中的逻辑

export function tqLeadSelect(tqLeadSelects): ng.IDirective {

var dir: ng.IDirective = {};

dir.scope = {
    tqModel: '=',
    tqCompany: '='
};

dir.restrict = 'E';
dir.templateUrl = '/js/templates/leadApp/tq-lead-select.html';
dir.replace = false;

dir.controller = function ($scope: any) {
    if (tqLeadSelects != null && $scope.tqCompany != null) {
        $scope.leads = tqLeadSelects.getLeadsFromFirma({ id: $scope.tqCompany });
    }

    $scope.$watch('tqCompany', (newValue, oldValue) => {
        if (newValue === oldValue) return;

        $scope.leads = tqLeadSelects.getLeadsFromFirma({ id: $scope.tqCompany });
    }, true);
}

return dir;
}

tqLeadSelect.$inject = ['tqLeadSelects'];
<ui-select ng-model="address.selected" theme="bootstrap" ng-disabled="disabled" reset-search-input="false" style="width: 300px;">
  <ui-select-match placeholder="Enter an address...">{{$select.selected.formatted_address}}</ui-select-match>
  <ui-select-choices repeat="address in addresses track by $index" refresh="refreshAddresses($select.search)" refresh-delay="0">
    <div ng-bind-html="address.formatted_address | highlight: $select.search"></div>
  </ui-select-choices>
</ui-select>
$scope.address = {};
$scope.refreshAddresses = function(address) {
  var params = {
    address: address,
    sensor: false
  };
  return $http.get(
    'http://maps.googleapis.com/maps/api/geocode/json', {
      params: params
    }
  ).then(function(response) {
    $scope.addresses = response.data.results
  });
};
<ui-select ng-model="adress.selected" tq-select></ui-select>
app.directive("tqSelect", function($http) {

  return {
    restrict: "A", // Attribute
    require: ["uiSelect", "ngModel"],

    compile: function compile(tElement, tAttrs, transclude) {

      // Add the inner content to the element
      tElement.append('<ui-select-match placeholder="Enter an address...">{{$select.selected.formatted_address}}</ui-select-match>\
      <ui-select-choices repeat="address in addresses track by $index" refresh="refreshAddresses($select.search)" refresh-delay="0">\
        <div ng-bind-html="address.formatted_address | highlight: $select.search"></div>\
      </ui-select-choices>');

      return {
        pre: function preLink(scope, iElement, iAttrs, controller) {},
        post: function postLink(scope, iElement, iAttrs, controller) {

          // logic from controller
          scope.address = {};
          scope.refreshAddresses = function(address) {
            var params = {
              address: address,
              sensor: false
            };
            return $http.get(
              'http://maps.googleapis.com/maps/api/geocode/json', {
                params: params
              }
            ).then(function(response) {
              scope.addresses = response.data.results
            });
          };
        }
      }
    }
  }
});