将适用的指令传递给自定义指令

时间:2016-04-22 15:30:54

标签: angularjs angularjs-directive

我理解如何通过我的自定义指令传递指令,如下所示:

page.html中

<my-directive read-only-attr="myVariable" label-style-attr="anotherVariable"></my-directive>

指令

myApp.directive("myDirective", function () {
  return {
    restrict: "E",
    templateUrl: "myTemplate.html",
    scope: {
      readOnlyScopeVar: "=readOnlyAttr",
      styleScopeVar: "=labelStyleAttr"
    },
    link: function (scope, element, attrs) {

    }
  };
});

模板

<div>
  <label ng-style="styleScopeVar" />
  <input type="text" ng-readonly="readOnlyScopeVar" />
</div>

我的模板比这复杂得多,但我简化了这个问题。

我的问题是:如果用户未在我的指令中指定“只读-attr”或“label-style-attr”,如何防止ngReadonly和ngStyle运行?有许多常见的角度指令,我想让人们应用于我的模板中的输入和其他元素(ngClass,ngDisabled,ngChange,ngPattern,ngIf等),但我不想全部运行它们如果人没有在我的指令上指明它们。就好像我需要一个模板来构建模板。

另外,请注意我已经阅读过关于翻译但我不喜欢允许用户直接编辑输入元素的想法,并且我可能想要应用的东西有多个元素,在这个例子中我可以如果只读-attr引用为true,则更改标签颜色。

1 个答案:

答案 0 :(得分:0)

一种方法是使用$ compile。这是一个有效的plnkr: https://plnkr.co/edit/S8pUSH?p=preview 请注意,有很多方法可以做到这一点,这只是一个简单的演示示例:

SELECT a.bcity, a.bstate, SUM(b.combo) as total
 FROM master a JOIN
       (SELECT id, SUM(doubles) + SUM(triples) as combo
  FROM batting 
  GROUP by id
 ) b 
 ON a.id = b.id
GROUP by a.bcity,a.bstate
ORDER BY total DESC
LIMIT 10;

请注意模板中的var app = angular.module('app', []); //define the module //setup the template app.run(['$templateCache', function($templateCache){ $templateCache.put('someDirectiveTmpl','<div>\ <label $$%%ngStylePlaceholder$$%% />My Label:</label>\ <input type="text" $$%%ngReadonlyPlaceholder$$%% />\ </div>'); }]) /** * @description someDirective gets a config object that holds dynamic directives' names and values. e.g.: * { * 'ngStyle': '{background: red;}', * 'ngReadonly': true * } * */ app.directive('someDirective', ['$log', '$compile', '$templateCache', function($log, $compile, $templateCache){ return { restrict: 'AE', controllerAs: 'someDirectiveCtrl', scope: {}, bindToController: { directiveConfig: '=' }, controller: function($scope, $element){ // a method to convert camelcase to dash function camelCaseToDash( myStr ) { return myStr.replace( /([a-z])([A-Z])/g, '$1-$2' ).toLowerCase(); } // get the template var template = $templateCache.get('someDirectiveTmpl'); var placeHolderRegExp = /\$\$%%(.*)\$\$%%/g; // place the binding per existing property angular.forEach(this.directiveConfig, function(varName, key){ template = template.replace('$$%%' + key + 'Placeholder$$%%', camelCaseToDash(key) + '="someDirectiveCtrl.directiveConfig.' + key + '"'); }); // remove unneeded properties placeholders template.replace(placeHolderRegExp, ''); //compile the directive var templateElement = angular.element(template); $compile(templateElement)($scope); // append to element $element.append(templateElement); } } }]); 。我从父指令获取配置(在plnkr中我为了简单起见使用了控制器)。我在示例中使用了配置对象(您可以使用单独的变量执行此操作,但我喜欢设置配置对象API)。 然后我根据配置中的内容替换占位符并删除我不需要的内容。然后我编译模板。 在父指令的控制器中,您可以执行类似于我在控制器中执行的操作:

$$%%ngAnythingPlaceholder$$%%
  

同样,我注意到你不应该使用控制器,当然,不要   使用$scope.config = { ngReadonly: true } 本身但指令的控制器$scope。我用   this和控制器只是为了便于演示。

您可以向此配置添加任何内容(当然,也可以将占位符添加到模板中的各种参数中)。 现在只需将指令添加到模板中:

$scope