2014-10-29 5 views
2

Я пытаюсь создать прокси-директиву, как так:AngularJS проксите директиву

<x-field x-purpose="choice" x-values="data.countries" ng-model="model.country"/> 

Если field директивы переадресует на другую директиву, вызывая следующую замену:

<x-choiceField x-values="data.countries" ng-model="model.country"/> 

[примечание:] ng-модель может быть заменена ссылкой на некоторую новую изолированную область.

Директива «field purpose» определяет, какую реализацию использовать (например, раскрывающийся список/список/автозаполнение?) В зависимости от того, сколько значений на выбор, размер клиентского устройства и т. Д. - в конечном итоге приводит к чему-то вроде этого:

<select ng-model="model.country" ng-options="data.countries"> 

Эта конструкция в основном из любопытства, а не для какой-либо практической причине, я заинтересован в том, как достичь его, а не является ли это на самом деле хорошая идея с точки производительность/простота зрения ...

После прочтения [https://stackoverflow.com/a/18895441/1156377], у меня есть что-то вроде этого:

function proxyDirective($injector, $parse, element) { 
    return function (scope, element, attrs) { 
     var target = element.camelCase(attrs.name + '-field'); 
     var model = attrs.ngModel; 
     var value = $parse(model); 
     var directive = $injector.get(target); 
     /* Bind ngModel to new isolated scope "value" property */ 
     scope.$watch(model, function() { 
      ??? 
     }); 
     /* Generate new directive element */ 
     var pElement = angular.element.html(''); 
     var pAttrs = { 
      value: ??? 
     }; 
     /* Forward to new directive */ 
     return directive.compile(element, attrs, null)(scope, element, attrs); 
    }; 
} 

function alphaFieldDirective() { 
    return { 
     replace: 'true', 
     template: '<input type="text" ng-value="forwarded value?">' 
    }; 
} 

function betaFieldDirective() { 
    return { 
     replace: 'true', 
     template: '<textarea attributes? >{{ value }}</textarea>' 
    }; 
} 

Но я не уверен, как достичь пересылки или переплета. Это мой первый корм в Angular директивы, и это, кажется, не особенно популярный способ их использования!

Целью этого является разделение цели поля формы от его внешнего вида/реализации и предоставление одной простой директивы для создания экземпляров полей.

+0

решаемые, я выложу ответ завтра, когда у меня будет полная работа демо. –

ответ

2

Я реализовал это с помощью сервиса, который прокси директивы:

Fiddle: http://jsfiddle.net/HB7LU/7779/

HTML:

<body ng-app="myApp"> 
    <h1>Directive proxying</h1> 
    <proxy target="bold" text="Bold text"></proxy> 
    <h1>Attribute forwarding</h1> 
    <proxy target="italic" style="color: red;" text="Red, italic text"></proxy> 
</body> 

Javascript:

angular.module('myApp', []) 
    .factory('directiveProxyService', directiveProxyService) 
    .directive('proxy', dirProxy) 
    .directive('bold', boldDirective) 
    .directive('italic', italicDirective) 
    ; 

function directiveProxyService($compile) { 
    return function (target, scope, element, attrs, ignoreAttrs) { 
     var forward = angular.element('<' + target + '/>'); 
     /* Move attributes over */ 
     _(attrs).chain() 
      .omit(ignoreAttrs || []) 
      .omit('class', 'id') 
      .omit(function (val, key) { return key.charAt(0) === '$'; }) 
      .each(function (val, key) { 
       element.removeAttr(attrs.$attr[key]); 
       forward.attr(attrs.$attr[key], val); 
      }); 
     $compile(forward)(scope); 
     element.append(forward); 
     return forward; 
    }; 
} 

function dirProxy(directiveProxyService) { 
    return { 
     restrict: 'E', 
     terminal: true, 
     priority: 1000000, 
     replace: true, 
     template: '<span></span>', 
     link: function (scope, element, attrs) { 
      directiveProxyService(attrs.target, scope, element, attrs, ['target']); 
     } 
    }; 
} 

function boldDirective() { 
    return { 
     restrict: 'E', 
     replace: true, 
     template: '<i>{{ text }}</i>', 
     scope: { text: '@' } 
    }; 
} 

function italicDirective() { 
    return { 
     restrict: 'E', 
     replace: true, 
     template: '<i>{{ text }}</i>', 
     scope: { text: '@' } 
    }; 
} 
Смежные вопросы