angularjs和google chrome扩展

angularjs和google chrome扩展,angularjs,google-chrome,google-chrome-extension,angularjs-factory,Angularjs,Google Chrome,Google Chrome Extension,Angularjs Factory,我有一个simpe google chrome扩展应用程序。我正在使用书签,它出现在清单文件中。首先,我在控制器中使用了chrome书签api,它运行良好。但我决定使用工厂来获得清晰的代码和最佳实践 My index.html文件 <!DOCTYPE html> <html lang="en" ng-app="BookmarksSharer" ng-csp> <head> <meta http-equiv="Content-Type" conte

我有一个simpe google chrome扩展应用程序。我正在使用书签,它出现在清单文件中。首先,我在控制器中使用了chrome书签api,它运行良好。但我决定使用工厂来获得清晰的代码和最佳实践

My index.html文件

<!DOCTYPE html>
<html lang="en" ng-app="BookmarksSharer" ng-csp>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>bokmarks sharer</title>
    <link rel="stylesheet" href="/css/main.css"/>
    <script src="/javascript/jquery-2.1.1.min.js"></script>
    <script src="/javascript/angular.min.js"></script>
    <script src="/javascript/bookmark_sharer.js"></script>
    <script src="/javascript/MainController.js"></script>
    <script src="/javascript/BookmarkService.js"></script>
</head>
<body>
    <div id="main_popup" ng-controller="MainController">
        <p>Bookmarks</p>
        <ul>
            <li ng-repeat="bookmark_folder in bookmarks_folders" id="{{bookmark_folder.title}}">
                {{bookmark_folder.title}}
                <ul ng-repeat="bookmarks in bookmark_folder">
                    <li ng-repeat="bookmark in bookmarks | filter">{{bookmark.title}}</li>
                </ul>
            </li>
        </ul>
    </div>
</body>
</html>
MainController.js也非常简单

app.controller('MainController',['$scope', 'bookmarkFactory', function($scope, bookmarkFactory){
    $scope.boormarks_folders = bookmarkFactory.folders;
}]);
还有我的工厂

app.factory('bookmarkFactory', function () {
    var bookmarks_folders;
    function allBookmarksFolders(){
        chrome.bookmarks.getTree(function(bookmarks_tree){
            bookmarks_folders = bookmarks_tree[0].children;
        });

        return bookmarks_folders;
    }

    return {
        folders: allBookmarksFolders()
    };
});
为什么$scope.bookmarks\u文件夹未定义

ExpertSystem您的代码也不工作。简单的解决办法是

app.controller('MainController',['$scope', function($scope){
    chrome.bookmarks.getTree(function(nodes){
        $scope.bookmarks_folders = nodes[0].children;
        $scope.$apply();
    })
}]);
但是我希望使用工厂或服务来组织代码。

是异步的,因此当
getAllBookmarks()
函数返回时,
bookmarks\u文件夹
是未定义的

您的服务公开一个属性(
文件夹
),该属性绑定到
allBookmarksFolders()
,唉
未定义
的结果

由于此操作是异步的,您的服务应该返回一个承诺,因此控制器可以使用该承诺并在返回时获取实际数据:

// The service
app.factory('bookmarkFactory', function ($q) {
    function retrieveAllBookmarksFolders() {
        var deferred = $q.defer();
        chrome.bookmarks.getTree(function (bookmarks_tree) {
            deferred.resolve(bookmarks_tree[0].children);
        });
        return deferred.promise;
    }

    return {
        foldersPromise: retrieveAllBookmarksFolders()
    };
});

// The controller
app.controller('MainController', function($scope, bookmarkFactory){
    bookmarkFactory.foldersPromise.then(function (bookmarks_folders) {
        $scope.boormarks_folders = bookmarks_folders;
    });
});

主要问题是,(在您的实现中)在该点返回绑定到
bookmarks\u folders
的值,然后重新分配
bookmarks\u folders
以保存对不同对象的引用(
bookmarks\u tree[0]。children

服务中的事件流有点像这样:

  • bookmarks\u文件夹
    已声明(并初始化为未定义)
  • allBookmarksFolders()
    被执行并返回(尚未定义的)
    bookmarks\u文件夹
  • 文件夹
    被指定为当前由
    书签\u文件夹
    引用的对象的引用(即未定义)
  • 执行
    getTree()
    回调,并向
    bookmarks\u文件夹
    分配对不同对象的引用(
    bookmarks\u树[0]。子对象
    )。此时,
    文件夹
    对此一无所知,并继续引用以前的值(未定义)
  • 另一种方法(由
    $resource
    btw使用的方法)是不将新引用分配给
    书签\u文件夹
    ,而是修改已引用的对象

    // The service
    app.factory('bookmarkFactory', function () {
        var bookmarks_folders = [];   // initialize to an empty array
        function allBookmarksFolders(){
            chrome.bookmarks.getTree(function(bookmarks_tree){
                // Here we need to modify the object (array)
                // already referenced by `bookmarks_folders`
    
                // Let's empty it first (just in case)
                bookmarks_folders.splice(0, bookmarks_folders.length);
    
                // Let's push the new data
                bookmarks_tree[0].children.forEach(function (child) {
                    bookmarks_folders.push(child);
                });
            });
    
            return bookmarks_folders;
        }
    
        return {
            folders: allBookmarksFolders()
        };
    });
    
    是异步的,因此当
    getAllBookmarks()
    函数返回时,
    bookmarks\u文件夹
    是未定义的

    您的服务公开一个属性(
    文件夹
    ),该属性绑定到
    allBookmarksFolders()
    ,唉
    未定义
    的结果

    由于此操作是异步的,您的服务应该返回一个承诺,因此控制器可以使用该承诺并在返回时获取实际数据:

    // The service
    app.factory('bookmarkFactory', function ($q) {
        function retrieveAllBookmarksFolders() {
            var deferred = $q.defer();
            chrome.bookmarks.getTree(function (bookmarks_tree) {
                deferred.resolve(bookmarks_tree[0].children);
            });
            return deferred.promise;
        }
    
        return {
            foldersPromise: retrieveAllBookmarksFolders()
        };
    });
    
    // The controller
    app.controller('MainController', function($scope, bookmarkFactory){
        bookmarkFactory.foldersPromise.then(function (bookmarks_folders) {
            $scope.boormarks_folders = bookmarks_folders;
        });
    });
    

    主要问题是,(在您的实现中)在该点返回绑定到
    bookmarks\u folders
    的值,然后重新分配
    bookmarks\u folders
    以保存对不同对象的引用(
    bookmarks\u tree[0]。children

    服务中的事件流有点像这样:

  • bookmarks\u文件夹
    已声明(并初始化为未定义)
  • allBookmarksFolders()
    被执行并返回(尚未定义的)
    bookmarks\u文件夹
  • 文件夹
    被指定为当前由
    书签\u文件夹
    引用的对象的引用(即未定义)
  • 执行
    getTree()
    回调,并向
    bookmarks\u文件夹
    分配对不同对象的引用(
    bookmarks\u树[0]。子对象
    )。此时,
    文件夹
    对此一无所知,并继续引用以前的值(未定义)
  • 另一种方法(由
    $resource
    btw使用的方法)是不将新引用分配给
    书签\u文件夹
    ,而是修改已引用的对象

    // The service
    app.factory('bookmarkFactory', function () {
        var bookmarks_folders = [];   // initialize to an empty array
        function allBookmarksFolders(){
            chrome.bookmarks.getTree(function(bookmarks_tree){
                // Here we need to modify the object (array)
                // already referenced by `bookmarks_folders`
    
                // Let's empty it first (just in case)
                bookmarks_folders.splice(0, bookmarks_folders.length);
    
                // Let's push the new data
                bookmarks_tree[0].children.forEach(function (child) {
                    bookmarks_folders.push(child);
                });
            });
    
            return bookmarks_folders;
        }
    
        return {
            folders: allBookmarksFolders()
        };
    });
    

    您是否调试并查看了此“书签”树[0]的内容。children;'在书签工厂中返回?当然,书签树[0]。子项返回正确的值。@Yegorodov:你看了我的答案了吗?它帮你解决了问题吗?如果是,请将其标记为已接受(也可以选择向上投票):)是否调试并查看此“书签”树[0]的内容。children;'在书签工厂中返回?当然,书签树[0]。子项返回正确的值。@Yegorodov:你看了我的答案了吗?它帮你解决了问题吗?如果是,请将其标记为已接受(也可以选择向上投票):)