Angularjs 和 Meteor“会话”反应,有没有办法?
Posted
技术标签:
【中文标题】Angularjs 和 Meteor“会话”反应,有没有办法?【英文标题】:Angularjs and Meteor "Session" reactivity, is there a way? 【发布时间】:2012-12-13 22:37:48 【问题描述】:我正在尝试使用 Meteor 和 Angularjs。我正在使用Meteor_angularjs 包,它适用于Collections
。
现在我正在尝试使用 Session
和我的反应式数据存储:
TestCtrl = [
"$scope",
function($scope)
$scope.value = Session.get('someValue');
]
这不起作用。
问题:关于如何绑定 Meteor 的 Session
和 Angular 有什么建议吗?
据我了解,我可以编写指令以每隔一段时间轮询Session
,但我认为这不是一个好的选择。
谢谢
更新:
我尝试了以下方法:
TestCtrl = [
"$scope",
function($scope)
Meteor.autorun(function()
$scope.config = Session.get('testsConfig');
if (!$scope.$$phase)
$scope.$digest();
);
]
它有点工作,但是我收到以下错误:
Error: INVALID_STATE_ERR: DOM Exception 11
Error: An attempt was made to use an object that is not, or is no longer, usable.
at derez (http://localhost:3000/test:95:41)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30)
at derez (http://localhost:3000/test:95:30) angular.js:5526
$get angular.js:5526
$get angular.js:4660
$get.Scope.$digest angular.js:7674
(anonymous function) controllers.js:46
Meteor.autorun.rerun deps-utils.js:78
_.extend.run deps.js:19
Meteor.autorun.rerun deps-utils.js:78
_.extend.flush deps.js:63
_.each._.forEach underscore.js:79
_.extend.flush deps.js:61
_.each._.forEach underscore.js:79
_.extend.flush deps.js:60
更新 2:
我已经尝试过这样的服务(可能是错误的用法),仍然没有。现在它根本不会更新 Session 值的变化。
Meteor.autorun(function()
app.factory('ssn', function() return
get: function(val)
return Session.get(val);
);
);
TestCtrl = [
"$scope","ssn",
function($scope, ssn)
$scope.config = ssn.get('testsConfig');
]
更新 3:Angular 有 $apply()
从角度框架之外执行角度表达式。 (例如来自浏览器 DOM 事件、setTimeout、XHR 或第三方库)
同时Meteor有Meteor.render()
为
不过,大多数时候,您不会直接调用这些函数——您只会使用您最喜欢的模板包,例如 Handlebars 或 Jade。 render 和 renderList 函数适用于实施新模板系统的人员。
但是,我似乎无法将 2 和 2 放在一起。 :(
【问题讨论】:
如果替换 'if (!$scope.$$phase) $scope.$digest(); 会发生什么' 由 $scope.$apply();? @asgoth,我收到Error: $digest already in progress
的其他错误
您是否尝试过创建服务并将其注入您的控制器?
【参考方案1】:
这是一个带有旧答案的老问题,但我看到人们提到它,所以这里是更新的答案。
首先 - 有一个 new library 用于 angular-meteor 为您处理这些情况。
而这个库为您提供了两种可能的解决方案:
如果要将会话变量绑定到范围变量,请使用$meteorSession 服务。 它的作用是每次范围变量发生变化时,它都会更改为 Session 变量(如果它被放置在一个变量中,则会触发自动运行)。 每次 Session 变量发生变化时,作用域变量也会发生变化(并改变它所在的视图)。
如果您使用 Session 变量只是为了获得变量响应(意味着触发自动运行),您应该使用 getReactively 。这只是返回已经存在的范围变量,但每次更改时都会触发自动运行。我们的tutorial 就是一个很好的例子。
注意:无论如何,当你在 Angular 中使用 Tracker.autorun 时,你需要将它连接到一个作用域。如果您将 Tracker.autorun 替换为 $meteorUtils autorun function,这可以轻松完成【讨论】:
我会盲目地接受你的答案,希望它是正确的并将它拉上流。我已经有一段时间没有做任何流星的东西了,所以无法验证。【参考方案2】:您好,这是一个选项(可能不是最好的,但我认为它有效)
app.service('Session',function($rootScope)
var self = this;
self.objects = ;
self.get = function(name)
self.objects[name] = "value" : Session.get(name);
Meteor.autorun(function()
var i = Session.get(name);
if(self.objects[name].value != i)
if (!$rootScope.$$phase)
$rootScope.$apply(function()
self.objects[name].value = i;
);
);
return self.objects[name];
self.set = function(name,value)
self.objects[name].value = value;
Session.set(name,value);
return self;
);
像这样在 $scope 中调用它 $scope.test = Session.get("test");
在视图中为 test.value。抱歉回复晚了。
新年快乐!
【讨论】:
是的,它确实有效,谢谢。但是,当我将Meteor.subscribe('tests', ssn.get('testsConfig')); $scope.Tests = new Meteor.AngularCollection("tests",$scope); $scope.tests = $scope.Tests.find();
放入同一个控制器时,我得到相同的错误Error: INVALID_STATE_ERR: DOM Exception 11
。任何想法为什么会发生这种情况?
我添加了最小的repo at github也许你可以看看?【参考方案3】:
试试
angular.module('yourmod', [])
.controller('TestCtrl', ['$scope', function($scope)
var c = Deps.autorun(function (comp)
//... put reactive stuf on scope.....
if(!comp.firstRun)
// only do not do aply at first run becaulse then apply is already running.
$scope.$apply()
);
// and to realy make it nice...
$scope.on('$destroy', function () c.stop());
])
【讨论】:
以上是关于Angularjs 和 Meteor“会话”反应,有没有办法?的主要内容,如果未能解决你的问题,请参考以下文章