angularjs and google chrome extension -
i have simpe google-chrome extension app. i'm using bookmarks , present in manifest file. firstly, use chrome bookmarks api in controller, , works well. decided use factory clear code , best practices.
my index.html file
<!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>
bookmark_sharer.js simple
var app = angular.module("bookmarkssharer", []);
maincontroller.js simple too.
app.controller('maincontroller',['$scope', 'bookmarkfactory', function($scope, bookmarkfactory){ $scope.boormarks_folders = bookmarkfactory.folders; }]);
and factory
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() }; });
why $scope.bookmarks_folders undefined?
expertsystem code not working too. simple solution is
app.controller('maincontroller',['$scope', function($scope){ chrome.bookmarks.gettree(function(nodes){ $scope.bookmarks_folders = nodes[0].children; $scope.$apply(); }) }]);
but want organize code using factories or services.
chrome.bookmarks.gettree()
asynchronous, time getallbookmarks()
function returns, bookmarks_folders
undefined.
your service exposes property (folders
) bound result of allbookmarksfolders()
, alas undefined
.
since operation asynchronous, service should return promise instead, controller can use promise , actual data when returnd:
// 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() }; }); // controller app.controller('maincontroller', function($scope, bookmarkfactory){ bookmarkfactory.folderspromise.then(function (bookmarks_folders) { $scope.boormarks_folders = bookmarks_folders; }); });
the main problem arises fact (in implementation) return value bound bookmarks_folders
@ point , later on re-assign bookmarks_folders
hold reference different object (bookmarks_tree[0].children
).
the flow of events inside service this:
bookmarks_folders
declared (and initialized undefined).allbookmarksfolders()
executed , returns (the still undefined)bookmarks_folders
.folders
assigned reference object referencedbookmarks_folders
(i.e. undefined).- the
gettree()
callback executes , assignsbookmarks_folders
reference different object (bookmarks_tree[0].children
). @ pointfolders
knows nothing , continues reference previous value (undefined).
an alternative approach (one used $resource
btw), not assign new reference bookmarks_folders
, modify referenced object.
// service app.factory('bookmarkfactory', function () { var bookmarks_folders = []; // initialize empty array function allbookmarksfolders(){ chrome.bookmarks.gettree(function(bookmarks_tree){ // here need modify object (array) // referenced `bookmarks_folders` // let's empty first (just in case) bookmarks_folders.splice(0, bookmarks_folders.length); // let's push new data bookmarks_tree[0].children.foreach(function (child) { bookmarks_folders.push(child); }); }); return bookmarks_folders; } return { folders: allbookmarksfolders() }; });
Comments
Post a Comment