[信息]
我想要实现的是实现一些自定义角度指令,这些指令将封装它们工作所需的所有JS。
指令不知道它们将显示什么以及存储来自用户的任何输入值的位置。这些信息将来自指令的属性。
我的指令将使用父范围,并且不会创建自己的范围。
[问题] 由于该指令不知道映射ng-model和ng-bind的$ scope中的位置,我的方法是读取指令的属性,确定ng-model和ng-bing属性应该是什么并设置它们到相应的元素。但这不起作用。我认为这是由于我缺乏知识所以我在这里问 - 如果我的方法还可以吗?是否可以以这种方式设置ngModel和ngBind?我做错了什么?。
[我的指令代码]
var directives = angular.module('test.directives', []);
directives.directive("labeledInput", function() {
return {
restrict: 'E',
scope: false,
template: "<div>" +
"<span class='label'></span>" +
"<input class='input' type='text'></input>" +
"</div>",
link: function(scope, element) {
var elementIdentifier = angular.element(element[0]).attr("idntfr");
var elementClass = angular.element(element[0]).attr("element-class");
var scopeValueName = angular.element(element[0]).attr("value-name");
var defaultValue = angular.element(element[0]).attr("default-value");
var elementLabel = angular.element(element[0]).attr("label");
scope[scopeValueName] = defaultValue;
scope[elementIdentifier] = elementLabel;
$(angular.element(element[0]).children()[0]).attr('id', elementIdentifier);
$(angular.element(element[0]).children()[0]).addClass(elementClass);
$(angular.element(element[0]).children().children()[1]).attr('ng-model', scopeValueName);
$(angular.element(element[0]).children().children()[0]).attr('ng-bind', elementIdentifier);
}
};
});
[结果]
因此,我在HTML页面中看到ng-model和ng-bind绑定在正确的位置,我有范围[scopeValueName] 和范围[elementIdentifier] 在Batarang提供的范围内,但我不会在屏幕上看到它们作为值。
有没有人解决过类似的问题?
谢谢你的时间!
[编辑] 对不起,似乎我的问题不明白我会添加一些细节!
以下是我的指令的HTML用法示例:
<labeled-input
idntfr='id001'
element-class='someClass'
value-name='person_name'
default-value='default'
label='Person Name:'
>
</labeled-input>
我在浏览器中对角度解析我的指令后所做的事情就是:
<div id="effect_dt" class="someClass">
<span class="label" ng-bind="id001"></span>
<input class="input" type="text" ng-model="person_name">
</div>
我在控制器范围内的内容是 - $ scope.id001 =&#34;人名:&#34;和$ scope.person_name =默认值。但是,这些值根本不会显示在页面上。
答案 0 :(得分:1)
如果我理解正确你想要做出类似的事情:
<labeledInput>model-name and/or field name</labeledInput>
并将其转换为:
<div>
<span class='label' ng-bind="mode-name.field-name"></span>
<input class='input' type='text'></input>
</div>
你必须在指令中阅读更多关于角度编译的内容,无论如何:
获取对指令原始内容的任何访问权限,例如您需要使用的属性或内部内容转换
访问模板内容(例如,在你的情况下让我们说'span'元素)你必须在编译方法中调用tElement参数,因为它将从模板中保存你的html
这里有一些很好的例子: Angularjs: transclude directive template
所有这些操作,例如添加ng-model属性指令等,你应该在指令编译之前添加,为此你必须使用编译块(代替你的'link()'块):
.compile = function compile(tElement, tAttrs) {
//here add some code eg append ng-model attribute etc.
return {
pre: function preLink(scope, iElement, iAttrs) {},
post: function postLink(scope, iElement, iAttrs) {}
}
}
和最后一部分 - 控制器范围,最简单的方法就是在模板中添加控制器,这样你就不会失去任何范围。
编辑:
在阅读了更新后的问题之后,请试一试:p
app.directive('labeledInput', function($compile) {
var directive = {};
directive.transclude = true;
directive.restrict = 'E';
directive.template = "<div>" +
"<span class='label' ></span><br/>" +
"<input class='input' type='text' ></input>" +
"</div>";
directive.compile = function(cElem, cAttrs) {
var scope=angular.element(cElem).scope();
console.log(scope);
var elementIdentifier = angular.element(cElem[0]).attr("idntfr");
var elementClass = angular.element(cElem[0]).attr("element-class");
var scopeValueName = angular.element(cElem[0]).attr("value-name");
var defaultValue = angular.element(cElem[0]).attr("default-value");
var elementLabel = angular.element(cElem[0]).attr("label");
$(cElem[0]).find("div").attr('id', elementIdentifier).addClass(elementClass);
$(cElem[0]).find("div span").attr('ng-bind', scopeValueName);
$(cElem[0]).find("div input").attr('ng-model', elementIdentifier);
return {
pre: function preLink(scope, iElement, iAttrs) {
scope[scopeValueName] = defaultValue;
scope[elementIdentifier] = elementLabel;
}
};
};
return directive;
});
答案 1 :(得分:0)
我不确定是否正确,但我想你想构建某种泛型指令,其行为来自父作用域并绑定到它的模板,在本例中是输入字段。
您可以在labeledInput指令上创建一个隔离范围,如下所示:
scope: {
doSomething:'&'
}
它的模板将成为: -
template: "<div>" +
"<span class='label'></span>" +
"<input class='input' type='text' ng-change="doSomething()"></input>" +
"</div>",
你的HTML将是: -
<labeledInput doSomething="someFunctionOnController()"></labeledInput>
因此,在更改输入字段时将调用控制器范围中定义的someFunctionOnController。
答案 2 :(得分:0)
有一种更简单的方法可以做到这一点:(见http://jsfiddle.net/j55B8/17/处的jsfiddle)
指令代码:
var directives = angular.module('test.directives', []);
directives.directive("labeledInput", function()
return {
restrict : "E",
replace : true,
scope : {
"idntfr" : "@",
"elementClass" : "@",
"valueName" : "=",
"defaultValue": "@",
"label" : "@"
},
template : "<div id='{{idntfr}}' class='{{elementClass}}' ng-init='valueName=defaultValue'>" +
"<span class='label' ng-bind='label'></span>" +
"<input class='input' type='text' ng-model='valueName'></input>" +
"</div>"
}
});
HTML
<labeled-input
idntfr='id001'
element-class='someClass'
value-name='person_name'
default-value='default name'
label='Person Name: '>
</labeled-input>
The value typed in the above text box is {{person_name}}