我在angularjs中创建了一个带有隔离范围和传递参数的自定义指令。 我尝试检查指令的控制器/链接中的参数,因为有时参数是一个数组,我只需要一个项目。但这不起作用(未定义的对象)。
directives.directive('dir.displaytaxoname', function () {
return {
restrict: 'E',
replace: true,
scope: {
dfamily: '@' ,
dgenus: '@',
dsn: '@'
},
controller: function ($scope) {
console.log($scope.dsn); // empty string in the console but ok in the rendered view
/*function tools_isArray(arr) { return ( arr instanceof Array ); }*/
// if the dfamily argument is an array i just want the first item
if(tools_isArray($scope.dfamily)){ $scope.dfamily = $scope.dfamily[0]; }
if(tools_isArray($scope.dgenus)){ $scope.dgenus = $scope.dgenus[0]; }
if(tools_isArray($scope.dsn)){ cl("indsn") ; $scope.dsn = $scope.dsn[0]; }
},
templateUrl: "partials/elements/displaytaxoname.html"
}
});
<span>
{{dfamily}} <i ng-show="dgenus!=''">{{dgenus}} </i><i>{{dsn}}</i><br>
</span>
<dir.displaytaxoname dfamily="{{specimen['T_FAMILY']}}"
dgenus="{{specimen['T_GENUS']}}"
dsn="{{specimen['T_SCIENTIFICNAME']}}">
</dir.displaytaxoname>
我尝试使用链接/控制器进行多次组合但不起作用。 我该怎么办?
感谢
答案 0 :(得分:2)
如果要将非字符串值传递给指令,则需要直接绑定到外部作用域表达式,而不是属性值(see documentation),因为属性值始终为String
此外,如果您不是100%确定编译指令时外部作用域上的数据已经存在,则需要$watch
数据而不是仅使用初始值。
scope: {
dfamily: '=', // bind to expression instead of attribute value
// ...
},
controller: function ($scope) {
// watch property value changes instead of using just the initial value
$scope.$watch('dfamily', function (value) {
if (tools_isArray(value)) {
// be extremely careful not to create an infinite cycle here
// (better save the modified values to different variables)
$scope.dfamily = value[0];
}
});
// ...
}
和
<tag dfamily="specimen['T_FAMILY']" ...></tag>
答案 1 :(得分:1)
您已使用=?
进行了测试scope: {
dfamily: '=' ,
dgenus: '=',
dsn: '='
}
答案 2 :(得分:0)
[基于@ hon2a答案的完整工作解决方案]
这是一个带有隔离范围的指令,它在参数中取一个数组。 它使用$ watch,因为在主控制器中的异步调用之后提供了数组参数
// in a asynchronus call to elasticsearch
elasticsearch.search({
index: $index,
size:1,
body: {
"query": $query
}
}).then(function (response) {
$scope.specimen = response.hits.hits[0]["_source"];
$scope.taxonamedata = {
"T_FAMILY" : $scope.specimen["T_FAMILY"] ,
"T_GENUS": $scope.specimen["T_GENUS"],
"T_SCIENTIFICNAME": $scope.specimen["T_SCIENTIFICNAME"], //scientific name
"D_IDENTIFIEDBY": $scope.specimen["D_IDENTIFIEDBY"],
"D_CREATED":$scope.specimen["D_CREATED"]
} ;
}
....
<dir.displaytaxoname data="taxonamedata"></dir.displaytaxoname>
directives.directive('dir.displaytaxoname', function ($filter) {
return {
restrict: 'E',
replace: true,
scope: {
data: '='
},
controller: function ($scope) {
// watch property value changes instead of using just the initial value
$scope.display = "";
$scope.$watch('data', function (value) {
if(tools_defined(value)){
var tmp = value; // copy it to tmp variable to avoid loop when change
for (var v in tmp) {
if (tools_isArray(tmp[v])) { // convert all the array to string
tmp[v] = tmp[v][0];
}
}
$scope.display = tmp["T_FAMILY"] + ' ';
if (tools_defined(tmp["T_GENUS"])) {
$scope.display += '<i>' + tmp["T_GENUS"] + '</i> ';
}
if (tools_defined(tmp["T_SCIENTIFICNAME"])) {
$scope.display += '<i>' + tmp["T_SCIENTIFICNAME"] + '</i><br>';
}
$scope.display += tmp["D_IDENTIFIEDBY"] ;
if (tools_defined(tmp["D_CREATED"])) {
$scope.display += ' ('+$filter('date')(tmp["D_CREATED"], "dd/MM/yyyy")+')';
}
}
});
},
plain:true,
template: '<span ng-bind-html="display | unsafe"></span>'
}
});
interfaceApp.filter('unsafe', function ($sce) {
return function (val) {
return $sce.trustAsHtml(val);
};
});
function tools_isArray(arr) {
return ( arr instanceof Array );
}
function tools_defined(object){
return (( typeof object != undefined) && ( typeof object != "undefined") && ( object != null ) ) ;
}