0

我正在尝试构建一个单页应用程序,其中列出了我的本地数据库(MongoDB)中的一些文件,但 AngularJS 没有向我显示数据。当我通过 Postman 从 Express-API 获取它们时,一切正常。我通过一个控制器获取它们,该控制器调用一个工厂,这是获取数据。但是当我从数据库中删除一个文件时,AngularJS 并没有更新表。当我重新加载页面时,它显示的是没有删除项目的正确数据,但为什么 2-way-databinding 不起作用?

这是我的 index.html 中的表格内容:

  <div ng-controller="FileCtrl">
    <div ng-hide="files.length" class="alert alert-warning">Noch keine Files vorhanden!</div>
    <table ng-show="files.length" class="table">
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Path</th>
        <th></th>
        <th></th>
      </tr>
      <tr ng-repeat="file in filtered = (files | filter:searchtext | orderBy: 'name')" class="files-item">
        <td>{{file._id}}</td>
        <td>{{file.name}}</td>
        <td>{{file.path}}</td>
        <td><a href class="btn btn-default btn-sm" ng-click="fileFactory.playFile(file);">Play</a></td>
        <td><a href class="btn btn-default btn-sm" ng-click="fileFactory.removeFile(file._id);">Delete</a> </td>
      </tr>
    </table>
  </div>

这是我的 app.js:

angular.module('picube', [])
.factory('fileFactory', function($http) {

    var files = [];
    return {
        getFiles: function(callback) {
            $http.get('http://localhost:8080/api/files/').then(function (Response) {   //takes all files from the api, tested with postman
                files = Response.data;  //Update Data
                callback(files);
            });
        },

        postFile: function(filepath){
            $http.post("http://localhost:8080/api/files/", filepath).then(function (Response) {   //adds a new file to the server-api, tested with postman
                files = Response.data;  //Update Data
            });
        },

        playFile: function(filepath){   //this is not important at the moment
            console.log("Play called");
            console.log(filepath);
        },

        removeFile: function(_id){ //deletes a file from server, tested with postman
            $http.delete("http://localhost:8080/api/files/" + _id).then(function(callback){
                files = callback.data;  //Update Data
            });
        }
    };
})
.controller('FileCtrl', function($scope, fileFactory) {
    $scope.fileFactory = fileFactory;

    init();

    function init() {
        fileFactory.getFiles(function(files){
            $scope.files = fileFactory.files;
        });
    }
});
4

3 回答 3

0

好的,现在它可以工作了。问题是导致错误的 files.length = 0。

原因是 angular.copy 会清除数组本身(请参见此处:array.copy)。这有效:

$http.get('http://localhost:8080/api/files/').then(function (Response) {
     angular.copy(Response.data, files);
});
于 2015-01-06T17:22:27.857 回答
0

我使用 ngresource/$resource 工厂而不是 $http 实现了我的数据库处理(更多信息可通过https://docs.angularjs.org/api/ngResource/service/$resource#的示例获得更多信息!)。

但是,它也应该可以与 $http 一起使用。我做了我的“removeFile”等效项,这样我实际上要么在删除后使用 GET 从服务器读取数据,要么当数据量变大时,最好使用 index 参数在 file[] 数组上使用 splice -method - 这是我对修改版本的建议,供您尝试:

...
 removeFile: function(_id, index){ //deletes a file from server, tested with postman
        $http.delete("http://localhost:8080/api/files/" + _id).then(function(callback){
            $scope.files.splice(index, 1);
        });
    }
...    

并相应地在 .html 中调用它以包含 $index:

...
<td>
    <a href class="btn btn-default btn-sm" ng-click = "fileFactory.removeFile(file._id, $index)">Delete</a>
</td>
...

这里的理由是,我认为您的 Delete 方法不会响应更新的完整文件列表 - 至少通常不会,但您必须自己更新本地内容。

希望这可以帮助...

于 2015-01-05T13:01:13.880 回答
0

您需要使用 angular.copy 来保留引用,否则您将覆盖它并破坏双向绑定:

$http.get('http://localhost:8080/api/files/').then(function (Response) {   //takes all files from the api, tested with postman
   files.length = 0; // clear the array
   angular.copy(Response.data, files);  //Update Data
        ...
});
于 2015-01-05T12:48:02.407 回答