Angular 指令模板未知范围
Angular directive template unknown scope
我知道有很多关于 AngularJS 以及应该如何使用指令的问题和帖子。我让我的工作正常,直到我遇到另一个我不知道如何解决的问题。
我在自定义 HTML 元素上使用指令。指令将此元素转换为模板中定义的常规 html 树。 HTML 元素有一些在构建模板时使用的属性。其中一个元素的数据通过 HTTP 请求接收并成功加载。这是我工作正常的部分。
现在我想做更多的事情。 I've created a plunker which is an example of what I want to achieve.虽然是假的,但很好地说明了我的问题。
index.html:
<body ng-controller="MainCtrl">
<div id="phones">
<phone brand="SmartBrand" model="xx" comment="blah"></phone>
<phone brand="SmarterBrand" model="abc" comment="other {{dynamic.c1}}"></phone>
</div>
</body>
Angular 指令:
app.directive('phone', function() {
return {
restrict: 'E',
replace: true,
scope: {
'comment': '@',
'brand': '@'
},
templateUrl: 'customTpl.html',
controller: function($scope) {
fakeResponse = {
"data": {
"success": true,
"data": "X300",
"dynamic": {
"c1": "12",
"c2": "1"
}
}
}
$scope.model = fakeResponse.data.data;
$scope.dynamic = fakeResponse.data.dynamic;
}
}
});
模板:
<div class="phone">
<header>
<h2>{{brand}} <strong>{{model}}</strong></h2>
</header>
<p>Comment: <strong>{{comment}}</strong></p>
</div>
所以我希望能够自定义元素中的标签之一(本例中的 phone 注释)。诀窍在于标签中的附加信息的数量可能会有所不同。我唯一可以确定的是名称将与从 AJAX 请求中收到的名称相匹配。我可以用 AJAX 接收整个评论,这将解决我的问题。但我想将模板与构建它的变量分开。可能吗?
好的,我成功了。它可能不是最先进的解决方案(我认为@xelilof 建议用另一个指令来做可能更正确),但我不知道如何做(所以请随时帮助我)。
我已经将 {{comment}}
部分变成了由服务分析的微模板。 I've made a plunk to show you a working sample.
JS 部分现在看起来像这样:
app.directive('phone', ['dynamic', function(dynamic) {
return {
restrict: 'E',
replace: true,
scope: {
'comment': '@',
'brand': '@',
'color': '@',
'photo': '@'
},
templateUrl: 'customTpl.html',
controller: function($scope) {
fakeResponse = {
"data": {
"success": true,
"data": "X300",
"dynamic": {
"c1": "12",
"c2": "2"
}
}
}
$scope.model = fakeResponse.data.data;
$scope.comment2 = dynamic($scope.comment, fakeResponse.data.dynamic);
console.log("Comment after 'dynamic' service is: " + $scope.comment);
}
}
}]);
app.factory('dynamic', function() {
return function(template, vars) {
for (var v in vars) {
console.log("Parsing variable " + v + " which value is " + vars[v]);
template = template.replace("::" + v + "::", vars[v]);
}
return template;
}
});
我知道有很多关于 AngularJS 以及应该如何使用指令的问题和帖子。我让我的工作正常,直到我遇到另一个我不知道如何解决的问题。
我在自定义 HTML 元素上使用指令。指令将此元素转换为模板中定义的常规 html 树。 HTML 元素有一些在构建模板时使用的属性。其中一个元素的数据通过 HTTP 请求接收并成功加载。这是我工作正常的部分。
现在我想做更多的事情。 I've created a plunker which is an example of what I want to achieve.虽然是假的,但很好地说明了我的问题。
index.html:
<body ng-controller="MainCtrl">
<div id="phones">
<phone brand="SmartBrand" model="xx" comment="blah"></phone>
<phone brand="SmarterBrand" model="abc" comment="other {{dynamic.c1}}"></phone>
</div>
</body>
Angular 指令:
app.directive('phone', function() {
return {
restrict: 'E',
replace: true,
scope: {
'comment': '@',
'brand': '@'
},
templateUrl: 'customTpl.html',
controller: function($scope) {
fakeResponse = {
"data": {
"success": true,
"data": "X300",
"dynamic": {
"c1": "12",
"c2": "1"
}
}
}
$scope.model = fakeResponse.data.data;
$scope.dynamic = fakeResponse.data.dynamic;
}
}
});
模板:
<div class="phone">
<header>
<h2>{{brand}} <strong>{{model}}</strong></h2>
</header>
<p>Comment: <strong>{{comment}}</strong></p>
</div>
所以我希望能够自定义元素中的标签之一(本例中的 phone 注释)。诀窍在于标签中的附加信息的数量可能会有所不同。我唯一可以确定的是名称将与从 AJAX 请求中收到的名称相匹配。我可以用 AJAX 接收整个评论,这将解决我的问题。但我想将模板与构建它的变量分开。可能吗?
好的,我成功了。它可能不是最先进的解决方案(我认为@xelilof 建议用另一个指令来做可能更正确),但我不知道如何做(所以请随时帮助我)。
我已经将 {{comment}}
部分变成了由服务分析的微模板。 I've made a plunk to show you a working sample.
JS 部分现在看起来像这样:
app.directive('phone', ['dynamic', function(dynamic) {
return {
restrict: 'E',
replace: true,
scope: {
'comment': '@',
'brand': '@',
'color': '@',
'photo': '@'
},
templateUrl: 'customTpl.html',
controller: function($scope) {
fakeResponse = {
"data": {
"success": true,
"data": "X300",
"dynamic": {
"c1": "12",
"c2": "2"
}
}
}
$scope.model = fakeResponse.data.data;
$scope.comment2 = dynamic($scope.comment, fakeResponse.data.dynamic);
console.log("Comment after 'dynamic' service is: " + $scope.comment);
}
}
}]);
app.factory('dynamic', function() {
return function(template, vars) {
for (var v in vars) {
console.log("Parsing variable " + v + " which value is " + vars[v]);
template = template.replace("::" + v + "::", vars[v]);
}
return template;
}
});