[英]Passing in $scope.$on name parameter as an attribute of an AngularJS directive
我正在嘗試創建一個指令,允許我傳入一個屬性字符串,然后在使用$ 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;
});
}]);
因此,我設法解決此特定問題的另一種方法是僅使用指令體中定義的內部DetailPaneController
。 我的一部分問題是,我通過將控制器作為父控制器使用ng-controller=
在我的html中以及在指令體中定義,使控制器實例化兩次。 這樣我就可以使用簡單的“@”綁定,並以正確的順序解決所有問題。 我甚至可以在我的模板中有另一個指令,我可以將validationResult
傳遞給它。
新設置如下所示:
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>
我將發布我的答案第一,鑒於它是一些代碼,如果這是必需的結果,請告訴我,所以我可以提供意見。 您應該能夠運行提供的代碼段。
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); });
<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>
我認為您應該在$ 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;
});
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.