如何使用XHR正确创建自己的角度服务?

时间:2015-02-21 01:34:08

标签: javascript angularjs

我对 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>  

屏幕

  

enter image description here
  列表中显示的示例帖子


问题

  

当我第一次点击添加新按钮时,一切正常,直到$scope.posts.push(result.post);。在控制台中, [SECOND OUT] 就在这里:

     

[SECOND OUT]
  第一个对象有 $$ hashKey ,但是从服务器发送的第二个对象(由$scope.posts.push(result.post);函数添加)没有。 我想知道为什么会这样??但这不仅奇怪,当我第二次点击添加新按钮时,所有内容都已成功完成(控制台中没有新日志,添加新帖子显示屏幕图像上面)。

主要原则
我从服务器推送了返回值,但第一次点击时帖子列表(在屏幕中)不受影响。

问题
 - 怎么了?或
 - 我究竟做错了什么?谢谢你的任何解释。

1 个答案:

答案 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将负责摘要周期调用。