Dob*_*007 68 javascript jquery angularjs
在控制器中,我使用$ http或$ resource服务获取一些JSON数据.然后我在$ scope中写这个数据,AngularJS更新页面的HTML结构.我的问题是我需要知道填充Angular ng-repeat
指令的列表的新大小(宽度和高度)是什么(我的意思是,HTML DOM元素).因此,我必须在Angular完成更新DOM结构后立即运行javascript代码.这样做的正确方法是什么?我在过去四个小时内搜索了互联网,但我找不到解决问题的方法.
这是我收到JSON数据的方式:
var tradesInfo = TradesInfo.get({}, function(data){
console.log(data);
$scope.source.profile = data.profile;
$scope.trades = $scope.source.profile.trades;
$scope.activetrade = $scope.trades[0];
$scope.ready = true;
init(); //I need to call this function after update is complete
});
Run Code Online (Sandbox Code Playgroud)
这就是init()
功能中发生的事情:
function init(){
alert($('#wrapper').width());
alert($('#wrapper').height());
}
Run Code Online (Sandbox Code Playgroud)
我知道必须有一些容易解决这个问题的东西,但我现在不能找到它.提前致谢.
Oli*_*ver 63
实际上在这种情况下,角度方式不是简单的方法,但唯一正确的方式:)
你必须写一个指令并附加到你想知道高度的元素.从控制器你广播一个事件,指令将捕获事件,你可以在那里进行DOM操作.永远不要在控制器中.
var tradesInfo = TradesInfo.get({}, function(data){
console.log(data);
$scope.source.profile = data.profile;
...
$scope.$broadcast('dataloaded');
});
directive('heightStuff', ['$timeout', function ($timeout) {
return {
link: function ($scope, element, attrs) {
$scope.$on('dataloaded', function () {
$timeout(function () { // You might need this timeout to be sure its run after DOM render.
element.width()
element.height()
}, 0, false);
})
}
};
}]);
Run Code Online (Sandbox Code Playgroud)
Olivér的答案很好,但有一个问题:如果您忘记播放该事件,您的javascript将无法运行,而您的数据可能已更改.另一种解决方案是观察范围的变化,例如:
var tradesInfo = TradesInfo.get({}, function(data) {
console.log(data);
$scope.profile = data.profile;
// ...
});
directive('heightStuff', ['$timeout',
function($timeout) {
return {
scope: {
myData: '='
},
link: function($scope, element, attrs) {
$scope.$watch('myData', function() {
$timeout(function() { // You might need this timeout to be sure its run after DOM render.
element.width()
element.height()
}, 0, false);
})
}
};
}
]);
Run Code Online (Sandbox Code Playgroud)
<div height-stuff my-data="profile"></div>
Run Code Online (Sandbox Code Playgroud)
这样,每次数据更改时都会调用javascript函数,而不需要自定义事件.
小智 5
使用JQuery的另一个建议.不得不通过一个指令生成的网格来解决这个问题.我想滚动到网格中的特定行.使用$ emit从指令广播到父控制器:
在控制器中:
['$timeout',function($timeout){
...
$scope.$on('dataloaded', function () {
$timeout(function () { // You might need this timeout to be sure its run after DOM render.
$scope.scrollToPosition();
}, 0, false);
});
$scope.scrollToPosition = function () {
var rowpos = $('#row_' + $scope.selectedActionID, "#runGrid").position();
var tablepost = $('table', "#runGrid").position();
$('#runGrid').scrollTop(rowpos.top - tablepost.top);
}
Run Code Online (Sandbox Code Playgroud)
在指令中
.directive('runGrid',['$timeout', function ($timeout) {
// This directive generates the grip of data
return {
restrict: 'E', //DOM Element
scope: { //define isolated scope
list: '=', //use the parent object
selected: "="
},
templateUrl: '/CampaignFlow/StaticContent/Runs/run.grid.0.0.0.0.htm', //HTML template URL
controller: ['$scope', function ($scope) { //the directive private controller, whith its private scope
//$scope.statusList = [{ data_1: 11, data_2: 12 }, { data_1: 21, data_2: 22 }, { data_1: 31, data_2: 32 }];
//Controller contains sort functionallity
$scope.sort = { column: null, direction: 1 }
$scope.column = null;
$scope.direction = "asc";
$scope.sortColumn = function (id) {
if(id!=$scope.column) {
$scope.column = id;
$scope.direction = "asc";
} else {
$scope.column = null;
}
}
$scope.toggleDir = function () {
$scope.direction = ($scope.direction == "asc") ? "desc" : "asc";
}
$scope.$emit('dataloaded');
}]
};
}])
Run Code Online (Sandbox Code Playgroud)
这是网格指令html模板的片段:
<div style="overflow-y:auto;height: 200px;" id="runGrid">
<table class="table table-striped" style="table-layout:fixed">
<tbody>
<tr ng-repeat="status in list" id="row_{{status.action_id}}" ng-class="(status.action_id==selected)?'selected':''">
<td>
Run Code Online (Sandbox Code Playgroud)
列表和所选参数是从使用该指令的html注入的
<run-grid list="list" selected="selectedActionID"></run-grid>
Run Code Online (Sandbox Code Playgroud)