在 Controller 异步调用后添加 CSS 样式的首选 AngularJS 方式是什么?
What is the preferred AngularJS way of adding CSS styling after Controller asynchronous call?
我正在使用 NW.js 和 AngularJS GitHub Link
构建应用程序
我的应用程序从本地文件夹中检索文件名并将这些文件名显示在应用程序中作为列表。我希望列表中的第一项看起来与其余项不同,因为它以 "selected" button/item 开头。文件数据是异步的。
目前,我将文件数据加载为一项服务,该服务将文件名拉入控制器内部。因为文件数据使用异步函数,所以我将它放在控制器中的 async.series 调用中。此异步调用完成后,ng-bind 生效,列表显示在我的应用程序中。
我尝试添加不同的指令以将所选 class 添加到第一项,但在列表显示在屏幕上之前它们都会被调用。
谁能帮我理解在元素绑定到数据后设置元素 classes 或 css 属性的首选 angularjs 方法是什么?
下面是相关代码。对于完整的项目,请遵循上面的 GitHub link。
控制器
fileVizApp.controller("fileVizController", function ($scope, configs, consoles, $location) {
var async = require('async');
var filehelper = require('filehelper');
var consoleKeys = [];
for(var key in consoles) {
consoleKeys.push(key);
}
async.each(consoleKeys, function(currConsole, callback) {
filehelper.GetItemList(consoles, currConsole, callback);
var a = 9;
}, function(err) {
if(err) {
return next(err);
}
$scope.headerSrc = "tmpl/header.html";
$scope.configs = configs;
$scope.back = function () {
window.history.back();
};
$scope.getCount = function (n) {
return new Array(n);
}
$scope.isActive = function (route) {
return route === $location.path();
}
$scope.isActivePath = function (route) {
return ($location.path()).indexOf(route) >= 0;
}
$scope.$apply( function () {
$scope.consoles = consoles;
if(consoles.length > 0) {
$scope.currConsoleInd = 0;
if(consoles.length > 1) {
$scope.nextConsoleInd = 1;
$scope.prevConsoleInd = consoles.length - 1;
} else {
$scope.nextConsoleInd = -1;
$scope.prevConsoleInd = -1;
}
}
else {
$scope.nextConsoleInd = -1;
$scope.prevConsoleInd = -1;
}
});
$scope.$broadcast("Consoles_Ready");
});
});
相关HTML
<!-- index.html -->
<!DOCTYPE html>
<html data-ng-app="fileVizApp">
<head>
<title>File Visualizer</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/app.css">
<link rel="stylesheet" type="text/css" href="css/sidebar.css">
<script type="text/javascript" src="js/lib/angular.min.js"></script>
<script type="text/javascript" src="js/lib/angular-resource.min.js"></script>
<script type="text/javascript" src="js/lib/angular-route.min.js"></script>
<script type="text/javascript" src="js/lib/jquery.min.js"></script>
<script type="text/javascript" src="js/lib/bootstrap.min.js"></script>
<script type="text/javascript" src="js/lib/ui-bootstrap-custom-tpls-0.13.0.min.js" ></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/service/services.js"></script>
<script type="text/javascript" src="js/controller/controllers.js"></script>
<script type="text/javascript" src="js/router/routes.js"></script>
<script type="text/javascript" src="js/directive/directives.js"></script>
</head>
<body class="container" data-ng-controller="fileVizController" main-directive>
<div data-ng-include src="headerSrc"></div>
<div id="container">
<div data-ng-view=""></div>
</div>
</body>
</html>
<!-- home.html-->
<div class="">
<!-- Sidebar -->
<ym-gamelist/>
<!-- /#sidebar-wrapper -->
</div>
<!-- itemlist.html -->
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<div ng-repeat="thisConsole in consoles">
<div ng-repeat="item in thisConsole.items" button-repeat>
<li>
<a class="itembutton" href="#"><span ng-bind="item"></span></a>
</li>
<li class="divider"></li>
</div>
</div>
</ul>
</div>
指令
fileVizApp.directive('ymGamelist', function() {
return {
restrict: 'AE',
scope: {},
controller: 'fileVizController',
link: function(scope, element, attrs) {
scope.$on('Consoles_Ready', function () {
var newa = 1;
});
},
compile: function (element, attrs) {
return {
pre: function(scope, iElem, iAttrs){
console.log(name + ': pre link => ' + iElem.html());
},
post: function(scope, iElem, iAttrs){
console.log(name + ': post link => ' + iElem.html());
}
}
},
templateUrl: 'tmpl/itemlist.html'
};
});
fileVizApp.directive('buttonRepeat', function($compile) {
return function(scope, element, attrs) {
if(scope.$last) {
scope.$emit('Itemlist_Loaded');
}
};
});
fileVizApp.directive('mainDirective', function() {
return function(scope, element, attrs) {
scope.$on('Itemlist_Loaded', function (event) {
$('.gamebutton').first().addClass('selectedbutton');
});
};
});
使用 ng-repeat
中可用的 $first
变量和 ng-class
来执行此操作。像这样
<div ng-repeat="item in thisConsole.items" button-repeat>
<li>
<a class="itembutton" href="#" ng-class={'selectedbutton':$first}><span ng-bind="item"></span></a>
</li>
<li class="divider"></li>
</div>
我正在使用 NW.js 和 AngularJS GitHub Link
构建应用程序我的应用程序从本地文件夹中检索文件名并将这些文件名显示在应用程序中作为列表。我希望列表中的第一项看起来与其余项不同,因为它以 "selected" button/item 开头。文件数据是异步的。
目前,我将文件数据加载为一项服务,该服务将文件名拉入控制器内部。因为文件数据使用异步函数,所以我将它放在控制器中的 async.series 调用中。此异步调用完成后,ng-bind 生效,列表显示在我的应用程序中。
我尝试添加不同的指令以将所选 class 添加到第一项,但在列表显示在屏幕上之前它们都会被调用。
谁能帮我理解在元素绑定到数据后设置元素 classes 或 css 属性的首选 angularjs 方法是什么?
下面是相关代码。对于完整的项目,请遵循上面的 GitHub link。
控制器
fileVizApp.controller("fileVizController", function ($scope, configs, consoles, $location) {
var async = require('async');
var filehelper = require('filehelper');
var consoleKeys = [];
for(var key in consoles) {
consoleKeys.push(key);
}
async.each(consoleKeys, function(currConsole, callback) {
filehelper.GetItemList(consoles, currConsole, callback);
var a = 9;
}, function(err) {
if(err) {
return next(err);
}
$scope.headerSrc = "tmpl/header.html";
$scope.configs = configs;
$scope.back = function () {
window.history.back();
};
$scope.getCount = function (n) {
return new Array(n);
}
$scope.isActive = function (route) {
return route === $location.path();
}
$scope.isActivePath = function (route) {
return ($location.path()).indexOf(route) >= 0;
}
$scope.$apply( function () {
$scope.consoles = consoles;
if(consoles.length > 0) {
$scope.currConsoleInd = 0;
if(consoles.length > 1) {
$scope.nextConsoleInd = 1;
$scope.prevConsoleInd = consoles.length - 1;
} else {
$scope.nextConsoleInd = -1;
$scope.prevConsoleInd = -1;
}
}
else {
$scope.nextConsoleInd = -1;
$scope.prevConsoleInd = -1;
}
});
$scope.$broadcast("Consoles_Ready");
});
});
相关HTML
<!-- index.html -->
<!DOCTYPE html>
<html data-ng-app="fileVizApp">
<head>
<title>File Visualizer</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/app.css">
<link rel="stylesheet" type="text/css" href="css/sidebar.css">
<script type="text/javascript" src="js/lib/angular.min.js"></script>
<script type="text/javascript" src="js/lib/angular-resource.min.js"></script>
<script type="text/javascript" src="js/lib/angular-route.min.js"></script>
<script type="text/javascript" src="js/lib/jquery.min.js"></script>
<script type="text/javascript" src="js/lib/bootstrap.min.js"></script>
<script type="text/javascript" src="js/lib/ui-bootstrap-custom-tpls-0.13.0.min.js" ></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/service/services.js"></script>
<script type="text/javascript" src="js/controller/controllers.js"></script>
<script type="text/javascript" src="js/router/routes.js"></script>
<script type="text/javascript" src="js/directive/directives.js"></script>
</head>
<body class="container" data-ng-controller="fileVizController" main-directive>
<div data-ng-include src="headerSrc"></div>
<div id="container">
<div data-ng-view=""></div>
</div>
</body>
</html>
<!-- home.html-->
<div class="">
<!-- Sidebar -->
<ym-gamelist/>
<!-- /#sidebar-wrapper -->
</div>
<!-- itemlist.html -->
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<div ng-repeat="thisConsole in consoles">
<div ng-repeat="item in thisConsole.items" button-repeat>
<li>
<a class="itembutton" href="#"><span ng-bind="item"></span></a>
</li>
<li class="divider"></li>
</div>
</div>
</ul>
</div>
指令
fileVizApp.directive('ymGamelist', function() {
return {
restrict: 'AE',
scope: {},
controller: 'fileVizController',
link: function(scope, element, attrs) {
scope.$on('Consoles_Ready', function () {
var newa = 1;
});
},
compile: function (element, attrs) {
return {
pre: function(scope, iElem, iAttrs){
console.log(name + ': pre link => ' + iElem.html());
},
post: function(scope, iElem, iAttrs){
console.log(name + ': post link => ' + iElem.html());
}
}
},
templateUrl: 'tmpl/itemlist.html'
};
});
fileVizApp.directive('buttonRepeat', function($compile) {
return function(scope, element, attrs) {
if(scope.$last) {
scope.$emit('Itemlist_Loaded');
}
};
});
fileVizApp.directive('mainDirective', function() {
return function(scope, element, attrs) {
scope.$on('Itemlist_Loaded', function (event) {
$('.gamebutton').first().addClass('selectedbutton');
});
};
});
使用 ng-repeat
中可用的 $first
变量和 ng-class
来执行此操作。像这样
<div ng-repeat="item in thisConsole.items" button-repeat>
<li>
<a class="itembutton" href="#" ng-class={'selectedbutton':$first}><span ng-bind="item"></span></a>
</li>
<li class="divider"></li>
</div>