AngularJS代理指令

AngularJS代理指令,angularjs,interface,proxy,directive,facade,Angularjs,Interface,Proxy,Directive,Facade,我正在尝试创建一个代理指令,如下所示: <x-field x-purpose="choice" x-values="data.countries" ng-model="model.country"/> [注意:]ng模型可以由对某个新的隔离范围的引用代替 “field purpose”指令根据可供选择的值数量、客户端设备大小等决定使用哪种实现(例如下拉/列表框/自动完成?)-最终导致如下结果: <select ng-model="model.country" ng-optio

我正在尝试创建一个代理指令,如下所示:

<x-field x-purpose="choice" x-values="data.countries" ng-model="model.country"/>
[注意:]ng模型可以由对某个新的隔离范围的引用代替

“field purpose”指令根据可供选择的值数量、客户端设备大小等决定使用哪种实现(例如下拉/列表框/自动完成?)-最终导致如下结果:

<select ng-model="model.country" ng-options="data.countries">
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>'
    };
} 

这种设计很大程度上是出于好奇,而不是出于任何实际原因。我感兴趣的是如何实现它,而不是从性能/简单性的角度来看,它是否真的是一个好主意

读完[,我有了这样的想法:

<select ng-model="model.country" ng-options="data.countries">
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>'
    };
} 
函数代理指令($injector,$parse,element){
返回函数(范围、元素、属性){
var target=element.camelCase(attrs.name+'-field');
var模型=attrs.ngModel;
var值=$parse(模型);
var指令=$injector.get(目标);
/*将ngModel绑定到新的隔离作用域“值”属性*/
范围:$watch(型号、功能(){
???
});
/*生成新的指令元素*/
var pElement=angular.element.html(“”);
变量参数={
值:???
};
/*转发新指令*/
compile(元素,attrs,null)(作用域,元素,attrs);
};
}
函数alphaFieldDirective(){
返回{
替换为:“true”,
模板:“”
};
}
函数betaFieldDirective(){
返回{
替换为:“true”,
模板:“{value}}”
};
} 
但我不确定如何实现转发或绑定。这是我第一次研究Angular指令,它似乎不是一种特别流行的使用方式


其目的是将表单字段的用途与其外观/实现分离,并提供一个用于实例化字段的简单指令。

我通过代理指令的服务实现了这一点:

小提琴:

HTML:


指令代理
属性转发
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: '@' }
    };
}
angular.module('myApp',[])
.factory('directiveProxyService',directiveProxyService)
.directive('proxy',dirProxy)
.指令(“粗体”,粗体指令)
.directive('italic',italicDirective)
;
函数定向代理服务($compile){
返回函数(目标、范围、元素、属性、ignoreAttrs){
var forward=角度元素(“”);
/*移动属性*/
_(attrs.chain()
.省略(忽略属性| |[]))
.omit('class','id'))
.omit(函数(val,key){return key.charAt(0)='$';})
.每个(功能(val、键){
element.removeAttr(attrs.$attr[key]);
forward.attr(attrs.$attr[key],val);
});
美元(远期)(范围);
元素。追加(转发);
向前返回;
};
}
函数dirProxy(directiveProxyService){
返回{
限制:'E',
终端:是的,
优先权:1000000,
替换:正确,
模板:“”,
链接:函数(范围、元素、属性){
directiveProxyService(attrs.target、scope、element、attrs、['target']);
}
};
}
函数boldDirective(){
返回{
限制:'E',
替换:正确,
模板:“{text}}”,
作用域:{text:'@'}
};
}
函数italicDirective(){
返回{
限制:'E',
替换:正确,
模板:“{text}}”,
作用域:{text:'@'}
};
}

解决了这个问题,明天我会在演示完成后发布答案。