如何在 javascript 数据字段中绑定 AngularJs 变量?
How to bind AngularJs variable inside javascript data field?
我想在 javascript 数据字段中绑定从 json 文件中获取的变量,但我不能使用 {{}} 运算符,因为它是在之后处理的。
<div class="milestone">
<div class="number" data-animation="true" data-animation-type="number" data-final-number="{{itemSold}}"></div>
<div class="title">Items Sold</div>
</div>
这样就给了我一个NaN,因为他看不到itemSold的值。
这就是 itemSold 的检索方式
var app = angular.module('app', []);
app.controller('AppCtrl', ['$scope', '$http', function($scope, $http)
{
$http.get('app/shared/homeStatistics.json').success(function(data){
$scope.itemSold = data.itemSold;
$scope.themeAndTemplate = data.themeAndTemplate;
$scope.members = data.members;
});
}]);
我想我必须使用之前处理过的类似 ng-bing 的东西,但我不知道如何。
感谢所有建议,抱歉我的英语不好
编辑 1
数据被正确检索,但在数据最终编号之后处理,所以他在开头读了一个“”
我的json数据
{
"itemSold":1000
}
编辑 2
这里是数据最终编号的处理方式
var handlePageScrollContentAnimation = function() {
$('[data-scrollview="true"]').each(function() {
var myElement = $(this);
var elementWatcher = scrollMonitor.create( myElement, 60 );
elementWatcher.enterViewport(function() {
$(myElement).find('[data-animation=true]').each(function() {
var targetAnimation = $(this).attr('data-animation-type');
var targetElement = $(this);
if (!$(targetElement).hasClass('contentAnimated')) {
if (targetAnimation == 'number') {
var finalNumber = parseInt($(targetElement).attr('data-final-number'));
$({animateNumber: 0}).animate({animateNumber: finalNumber}, {
duration: 1000,
easing:'swing',
step: function() {
var displayNumber = handleAddCommasToNumber(Math.ceil(this.animateNumber));
$(targetElement).text(displayNumber).addClass('contentAnimated');
}
});
} else {
$(this).addClass(targetAnimation + ' contentAnimated');
}
}
});
});
});
};
大多数情况下都可以。如果您不想要任何 NaN
,您有几个选择:
- 初始化作用域变量,例如 'Pending...'
- 用
ng-if
或ng-show
包裹起来
- 更复杂的解决方案(例如 rest-angular)
如果我没理解错的话,您想在 component/directive/controller 加载后立即获得数据。
在那种情况下 - 在控制器中使用 resolve,它会将您的 ajax 请求的结果注入控制器,并且在加载控制器时您将拥有所有数据。
路由器
app.config(function ($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: "app.html",
controller: "AppCtrl"
resolve: {
statResponse: function () {
return $http.get('app/shared/homeStatistics.json');
}
}
}
)
});
控制器
app.controller('AppCtrl', ['$scope', 'statResponse', function($scope, statResponse)
{
if(statResponse && statResponse.status === 200) {
$scope.itemSold = statResponse.data.itemSold;
$scope.themeAndTemplate = statResponse.data.themeAndTemplate;
$scope.members = statResponse.data.members;
}
}]);
另一种方法是在元素上使用 ng-cloak。它将隐藏元素,直到所有变量都被解析。
<div class="number" ng-cloak data-animation="true" data-animation-type="number" data-final-number="{{itemSold}}"></div>
希望对您有所帮助。
显然,您正在尝试处理 data-final-number="{{itemSold}}"
属性 ,然后再 它已被解析。要处理它 after,请确保仅调用处理程序 after 你已经检索到 JSON 数据和 AngularJS 生命周期已经为你解决了。为此,您可以使用 AngularJS 的 $timeout
,因此它将在 AngularJS 操作之后被排队并执行。
var app = angular.module('app', []);
app.controller('AppCtrl', ['$scope', '$http', function($scope, $http, $timeout)
{
$http.get('app/shared/homeStatistics.json').success(function(data){
$scope.itemSold = data.itemSold;
$scope.themeAndTemplate = data.themeAndTemplate;
$scope.members = data.members;
//calling handler after AngularJS applied all two-way-bindings
$timeout(function() {
handlePageScrollContentAnimation();
}, 0);
});
}]);
更多信息,请阅读:Anyway to trigger a method when Angular is done adding scope updates to the DOM?
我建议使用 attr.$observer 和 finalNumber
指令。每当有更新时,这将触发一个要执行的函数。话虽如此,它不仅呈现一次,每当值更改时,视图都会更新。
.directive('finalNumber',function() {
function link(scope, element, attrs) {
$attrs.$observe('finalNumber', function(value) {
if (!isNaN(value)){
//update accordingly, it's kind of hack to
//bring this code to angular. It's better to write all these
// as angular directives.
handlePageScrollContentAnimation();
}
});
}
return {
link: link
};
});
从 jQuery 后台迁移到 angular 时,您需要改变心态。 Angular 是一个 MVC 框架,主要基于 databinding。使用数据绑定,视图不应该关心模型何时以及如何更新,但只要有更新,视图就应该知道并更新视图因此。
上面的例子应该是使用 angular 的正确方法。但正如我所说,将你的 jQuery 代码带到 angular 是一个很麻烦的事情,所有这些都应该写成指令。我不确定您是否需要 运行 您的 jQuery 代码仅 一次 (运行 多次可能会导致副作用)更新。您可能需要一些技巧。 不推荐,如果可能,您应该将所有这些写成指令 (scrollview
,animation
,finalNumber
,..)
.directive('finalNumber',function() {
function link(scope, element, attrs) {
var hasRun = false;//hack the code to run only once.
$attrs.$observe('finalNumber', function(value) {
if (!isNaN(value) && !hasRun){
//update accordingly, it's kind of hack to
//bring this code to angular. It's better to write all these
// as angular directives.
handlePageScrollContentAnimation();
}
});
}
return {
link: link
};
});
我想监视 'itemSold' 变量,每当从 $http 调用中获取值时,我都会调用 handlePageScrollContentAnimation 处理程序。
var watchItemSold = $scope.$watch('itemSold', function(newVal, oldVal, scope){
if(newVal != oldVal){
handlePageScrollContentAnimation(); //call handler
watchItemSold(); //watch destructor will ensure that handler will call once
}
});
希望对您有所帮助。谢谢。
我想在 javascript 数据字段中绑定从 json 文件中获取的变量,但我不能使用 {{}} 运算符,因为它是在之后处理的。
<div class="milestone">
<div class="number" data-animation="true" data-animation-type="number" data-final-number="{{itemSold}}"></div>
<div class="title">Items Sold</div>
</div>
这样就给了我一个NaN,因为他看不到itemSold的值。
这就是 itemSold 的检索方式
var app = angular.module('app', []);
app.controller('AppCtrl', ['$scope', '$http', function($scope, $http)
{
$http.get('app/shared/homeStatistics.json').success(function(data){
$scope.itemSold = data.itemSold;
$scope.themeAndTemplate = data.themeAndTemplate;
$scope.members = data.members;
});
}]);
我想我必须使用之前处理过的类似 ng-bing 的东西,但我不知道如何。
感谢所有建议,抱歉我的英语不好
编辑 1
数据被正确检索,但在数据最终编号之后处理,所以他在开头读了一个“”
我的json数据
{
"itemSold":1000
}
编辑 2
这里是数据最终编号的处理方式
var handlePageScrollContentAnimation = function() {
$('[data-scrollview="true"]').each(function() {
var myElement = $(this);
var elementWatcher = scrollMonitor.create( myElement, 60 );
elementWatcher.enterViewport(function() {
$(myElement).find('[data-animation=true]').each(function() {
var targetAnimation = $(this).attr('data-animation-type');
var targetElement = $(this);
if (!$(targetElement).hasClass('contentAnimated')) {
if (targetAnimation == 'number') {
var finalNumber = parseInt($(targetElement).attr('data-final-number'));
$({animateNumber: 0}).animate({animateNumber: finalNumber}, {
duration: 1000,
easing:'swing',
step: function() {
var displayNumber = handleAddCommasToNumber(Math.ceil(this.animateNumber));
$(targetElement).text(displayNumber).addClass('contentAnimated');
}
});
} else {
$(this).addClass(targetAnimation + ' contentAnimated');
}
}
});
});
});
};
大多数情况下都可以。如果您不想要任何 NaN
,您有几个选择:
- 初始化作用域变量,例如 'Pending...'
- 用
ng-if
或ng-show
包裹起来
- 更复杂的解决方案(例如 rest-angular)
如果我没理解错的话,您想在 component/directive/controller 加载后立即获得数据。
在那种情况下 - 在控制器中使用 resolve,它会将您的 ajax 请求的结果注入控制器,并且在加载控制器时您将拥有所有数据。
路由器
app.config(function ($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: "app.html",
controller: "AppCtrl"
resolve: {
statResponse: function () {
return $http.get('app/shared/homeStatistics.json');
}
}
}
)
});
控制器
app.controller('AppCtrl', ['$scope', 'statResponse', function($scope, statResponse)
{
if(statResponse && statResponse.status === 200) {
$scope.itemSold = statResponse.data.itemSold;
$scope.themeAndTemplate = statResponse.data.themeAndTemplate;
$scope.members = statResponse.data.members;
}
}]);
另一种方法是在元素上使用 ng-cloak。它将隐藏元素,直到所有变量都被解析。
<div class="number" ng-cloak data-animation="true" data-animation-type="number" data-final-number="{{itemSold}}"></div>
希望对您有所帮助。
显然,您正在尝试处理 data-final-number="{{itemSold}}"
属性 ,然后再 它已被解析。要处理它 after,请确保仅调用处理程序 after 你已经检索到 JSON 数据和 AngularJS 生命周期已经为你解决了。为此,您可以使用 AngularJS 的 $timeout
,因此它将在 AngularJS 操作之后被排队并执行。
var app = angular.module('app', []);
app.controller('AppCtrl', ['$scope', '$http', function($scope, $http, $timeout)
{
$http.get('app/shared/homeStatistics.json').success(function(data){
$scope.itemSold = data.itemSold;
$scope.themeAndTemplate = data.themeAndTemplate;
$scope.members = data.members;
//calling handler after AngularJS applied all two-way-bindings
$timeout(function() {
handlePageScrollContentAnimation();
}, 0);
});
}]);
更多信息,请阅读:Anyway to trigger a method when Angular is done adding scope updates to the DOM?
我建议使用 attr.$observer 和 finalNumber
指令。每当有更新时,这将触发一个要执行的函数。话虽如此,它不仅呈现一次,每当值更改时,视图都会更新。
.directive('finalNumber',function() {
function link(scope, element, attrs) {
$attrs.$observe('finalNumber', function(value) {
if (!isNaN(value)){
//update accordingly, it's kind of hack to
//bring this code to angular. It's better to write all these
// as angular directives.
handlePageScrollContentAnimation();
}
});
}
return {
link: link
};
});
从 jQuery 后台迁移到 angular 时,您需要改变心态。 Angular 是一个 MVC 框架,主要基于 databinding。使用数据绑定,视图不应该关心模型何时以及如何更新,但只要有更新,视图就应该知道并更新视图因此。
上面的例子应该是使用 angular 的正确方法。但正如我所说,将你的 jQuery 代码带到 angular 是一个很麻烦的事情,所有这些都应该写成指令。我不确定您是否需要 运行 您的 jQuery 代码仅 一次 (运行 多次可能会导致副作用)更新。您可能需要一些技巧。 不推荐,如果可能,您应该将所有这些写成指令 (scrollview
,animation
,finalNumber
,..)
.directive('finalNumber',function() {
function link(scope, element, attrs) {
var hasRun = false;//hack the code to run only once.
$attrs.$observe('finalNumber', function(value) {
if (!isNaN(value) && !hasRun){
//update accordingly, it's kind of hack to
//bring this code to angular. It's better to write all these
// as angular directives.
handlePageScrollContentAnimation();
}
});
}
return {
link: link
};
});
我想监视 'itemSold' 变量,每当从 $http 调用中获取值时,我都会调用 handlePageScrollContentAnimation 处理程序。
var watchItemSold = $scope.$watch('itemSold', function(newVal, oldVal, scope){
if(newVal != oldVal){
handlePageScrollContentAnimation(); //call handler
watchItemSold(); //watch destructor will ensure that handler will call once
}
});
希望对您有所帮助。谢谢。