我对 AngularJS 的事情非常了解。需要使用表单中的其他数据进行文件上传,我找到了一些脚本和角度插件,但我使用自己的服务调用 $ xhr 。我能够发送文件,但我得到错误,错误(不是真正的错误错误,我只是命名为)或者我无法正确使用AngularJS。这是:
。
的 JS
var app = angular.module('ngnNews', []);
app.factory('posts', [function () {...}]); // I reduced the codes
app.factory('$xhr', function () {
var $xhr = { reqit: function (components) { ... //My Xml HTTP Request codes here }}
return $xhr;
});
app.controller('MainCtrl', ['$http','$scope','$xhr','posts',
function ($http, $scope, $xhr, posts) {
$scope.posts = posts.posts;
$scope.files = [];
var newPost = { title: 'post one', upvotes: 20, downvotes: 5 };
$scope.posts.push(newPost);
$scope.addPost = function () {
$xhr.reqit({
form: document.getElementById('postForm'),
callbacks: {
success: function (result) {
if (result.success) {
console.log($scope.posts); //[FIRST OUT]
$scope.posts.push(result.post);
$scope.title = '';
console.log($scope.posts); //[SECOND OUT]
}
}
},
values: { upvotes: 0, downvotes: 0 },
files: $scope.files
});
...
}
}]);
。
的 HTML
<form action="/Home/FileUp" id="postForm" method="post" enctype="multipart/form-data">
<div class="form-group input-group">
<span class="input-group-addon">Post Title</span>
<input name="title" class="form-control" type="text" data-ng-model="title" />
</div>
<ul>
<li ng-repeat="file in files">{{file.name}}</li>
</ul>
<button class="btn btn-primary" type="button" data-ng-click="addPost()">Add New</button>
</form>
屏幕
列表中显示的示例帖子
。
问题
当我第一次点击添加新按钮时,一切正常,直到
$scope.posts.push(result.post);
。在控制台中, [SECOND OUT] 就在这里:
第一个对象有 $$ hashKey ,但是从服务器发送的第二个对象(由$scope.posts.push(result.post);
函数添加)没有。 我想知道为什么会这样??但这不仅奇怪,当我第二次点击添加新按钮时,所有内容都已成功完成(控制台中没有新日志,添加新帖子显示屏幕图像上面)。
主要原则
我从服务器推送了返回值,但第一次点击时帖子列表(在屏幕中)不受影响。
问题
- 怎么了?或
- 我究竟做错了什么?谢谢你的任何解释。
答案 0 :(得分:1)
如果您关注$$hashkey
,那么您没有做错任何事。当您使用带有对象数组的ng-repeat时,默认情况下会将唯一键附加到具有属性$$hashkey
的项目。然后,此属性用作关联DOM元素与按标识的数组中相应项的关键字。在数组中移动相同的对象将以相同的方式在DOM中移动DOM元素。您可以通过在对象上提供唯一键或仅track by
使用带有ng-repeat的$index
来避免这种情况(通过角度在对象上添加其他属性)。因此,使用它而不是创建唯一键并将其附加到$$ haskey属性angular将使用您提供的唯一标识符将DOM元素与相应的数组项关联。
ng-repeat="post in posts track by $index"
或(对于数组中的每个对象,您都有一个唯一的ID,比如说id
)
ng-repeat="post in posts track by post.id"
由于您说您正在使用my xml http request code here
,我假设它不在角度上下文中,因此您需要使用$scope.$apply()
手动执行摘要周期。< / p>
$scope.addPost = function () {
$xhr.reqit({
form: document.getElementById('postForm'),
callbacks: {
success: function (result) {
if (result.success) {
$scope.posts.push(result.post);
$scope.title = '';
$scope.$apply();//<-- here
}
}
},
但理想情况下,您可以使用$q
包装xhr实现,如果从api传递$ q promise,则无需在任何地方执行手册$scope.$apply()
。因为$ q promise chaining将负责摘要周期调用。