我正在尝试创建一个指令,允许我传入一个属性字符串,然后在使用$ scope。$ on订阅事件时将其用作“name”参数。基本上,一系列事件是这样的:
问题是,在评估所有内容时,属性的值似乎是“未定义的”,因此当我尝试使用$ scope。$ on进行订阅时,它实际上将我订阅为“undefined”而不是“validationResultMessage”
这是我的指示:
app.directive('detailPane', function () {
return {
restrict: 'E',
scope: {
selectedItem: '=',
subscription: '@',
},
templateUrl: 'app/templates/DetailPane.html', //I'm also worried that this is causing my controller to get instantiated twice
controller: 'DetailPaneController'
};
});
然后我这样使用:
<td class="sidebar" ng-controller="DetailPaneController" ng-style="{ 'display': sidebarDisplay }">
<detail-pane
selected-item='validationResult'
subscription='validationResultMessage'/>
</td>
我试图将此属性传递给控制器:
app.controller('DetailPaneController', ['$scope', '$http', 'dataService', 'toastr', '$uibModal', '$rootScope', '$attrs', function ($scope, $http, dataService, toastr, $uibModal, $rootScope, $attrs) {
$scope.fetching = [];
$scope.validationResult = null;
$scope.sidebarDisplay = 'block';
console.log('subscription is ', $scope.subscription);
var thisSubscription = $scope.subscription;
//if I hardcode the param as 'validationResultMessage', this works
$scope.$on($scope.subscription, function (event, arg) {
$scope.validationResult = arg;
});
}]);
答案 0 :(得分:2)
因此,我设法解决此特定问题的另一种方法是仅使用指令体中定义的内部DetailPaneController
。我的一部分问题是我通过在html中使用ng-controller=
作为父控制器以及在指令体中定义来使控制器实例化两次。这样我就可以直接使用&#34; @&#34;绑定,一切都按正确的顺序解决。我甚至可以在我的模板中有另一个指令,我可以将validationResult
传递给。{/ p>
新设置如下所示:
<强> DetailPaneController:强>
app.controller('DetailPaneController', ['$scope', '$http', function ($scope, $http) {
$scope.$on($scope.subscription, function (event, arg) {
$scope.validationResult = arg;
$scope.exception = JSON.parse(arg.Exception);
});
}]);
DetailPane指令:
app.directive('detailPane', function () {
return {
restrict: 'E',
scope: {
subscription: '@' //notice I am no longer binding to validationResult
},
templateUrl: 'app/templates/DetailPane.html',
controller: 'DetailPaneController'
};
});
HTML中使用的指令:
<div class="sidebar" ng-style="{ 'display': sidebarDisplay }">
<detail-pane subscription='validationResultMessage' />
</div>
指令模板(为了更好的衡量标准):
<div class="well sidebar-container">
<h3>Details</h3>
<div ng-show="validationResult == null" style="padding: 15px 0 0 15px;">
<h5 class=""><i class="fa fa-exclamation-triangle" aria-hidden="true" /> Select a break to view</h5>
</div>
<div ng-show="validationResult != null">
<table class="table table-striped">
<tr ng-repeat="(key, value) in validationResult">
<td class="sidebar-labels">{{key | someFilter}}</td>
<td >{{value | someOtherFilter : key}}</td>
</tr>
</table>
<another-directive selected-item="validationResult" endpoint="endpoint" />
</div>
答案 1 :(得分:1)
我将发布我的答案第一,鉴于它是一些代码,请告诉我这是否是必需的结果,所以我可以提供意见。您应该能够运行提供的代码段。
var app = angular.module('myApp', []);
app.directive('detailPane', function() {
return {
restrict: 'E',
transclude: false,
scope: {
selectedItem: '=',
subscription: '@'
},
link: function(scope, elem, attr) {
scope.$on(scope.subscription, function(e, data) {
scope.selectedItem = data.result;
elem.text(data.message);
});
},
};
});
app.controller('DetailPaneController', function($scope) {
$scope.validationResult1 = "";
$scope.validationResult2 = "";
});
app.controller('SecondController', function($rootScope, $scope, $timeout) {
$timeout(function() {
$rootScope.$broadcast('validationResultMessage1', {
message: 'You fail!',
result: 'Result from 1st fail'
})
}, 2000);
$timeout(function() {
$rootScope.$broadcast('validationResultMessage2', {
message: 'You also fail 2!',
result: 'Result from 2nd fail'
})
}, 4000);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app='myApp'>
<div ng-controller="DetailPaneController">
<detail-pane class='hello' selected-item='validationResult1' subscription='validationResultMessage1'></detail-pane>
<br/>
<detail-pane class='hello' selected-item='validationResult2' subscription='validationResultMessage2'></detail-pane>
<hr/>
<span>{{validationResult1}}</span>
<br/>
<span>{{validationResult2}}</span>
</div>
<div ng-controller="SecondController">
</div>
</body>
&#13;
答案 2 :(得分:0)
我认为您应该在$ scope.subscription上设置观察者并检查是否设置了新值,然后开始订阅传递的事件。
$scope.$watch('subscription', function(nv, ov){
//this makes sure it won't trigger at initialization
if(nv!==ov){
$scope.$on($scope.subscription, function (event, arg) {
$scope.validationResult = arg;
});
}
});