我正在为mvc4使用Durandal Starter Template。我设置了以下简单视图:
<section>
<h2 data-bind="html: displayName"></h2>
<h3 data-bind="html: posts"></h3>
<button data-bind="click: getrss">Get Posts</button>
<div id="rsstestid" ></div>
</section>
和ViewModel:
define(function (require) {
var http = require('durandal/http'),
app = require('durandal/app');
return {
displayName: 'This is my RssTest',
posts: ko.observable(),
activate: function () {
return;
},
getrss: function () {
$('#rsstestid').rssfeed('http://feeds.reuters.com/reuters/oddlyEnoughNews');
return;
}
};
});
正如您所看到的,当单击“获取帖子”按钮时,只需使用zRssReader插件将帖子加载到div中。一切正常,显示名称已填充,帖子按预期显示。
我遇到麻烦的时候是我尝试删除按钮并尝试在创建时加载帖子。如果我将插件调用放在activate函数中,我将得不到任何结果。我假设这是因为视图未完全加载,因此该元素不存在。我有两个问题:
感谢您的帮助。
答案 0 :(得分:4)
编辑**以下答案适用于durandal 1.2。在durandal 2.0 viewAttached
已更改为attached
直接从durandaljs.com粘贴的副本
“每当Durandal编写时,它还会检查您的模型中是否有一个名为viewAttached
的函数。如果它存在,它将调用该函数并将绑定视图作为参数传递。这允许控制器或演示者拥有直接访问它在注入父节点后的某个时间点所绑定的dom子树。
注意:如果您设置了cacheViews:true
,则只会在初始绑定时第一次显示视图时调用viewAttached
,因为从技术上讲,视图仅附加一次。如果您希望覆盖此行为,请在合成绑定上设置alwaysAttachView:true
。“
- quoted from the site
有很多方法可以做到,但这只是一种快速而又脏的方式:
<section>
<h2 data-bind="html: displayName"></h2>
<h3 data-bind="html: posts"></h3>
<button data-bind="click: getRss">Get Posts</button>
<div id="rsstestid"></div>
</section>
和代码:
define(function (require) {
var http = require('durandal/http'),
app = require('durandal/app');
var $rsstest;
return {
displayName: 'This is my RssTest',
posts: ko.observable(),
viewAttached: function(view) {
$rssTest = $(view).find('#rsstestid');
},
getRss: function() {
$rssTest.rssfeed('http://feeds.reuters.com/reuters/oddlyEnoughNews');
}
};
});
答案 1 :(得分:2)
一般来说,我认为避免直接触摸视图模型中的UI元素是明智的。
一个好方法是创建一个可以呈现rss feed的自定义KO绑定。这样,您可以保证在绑定执行时视图就位。您可能希望将Feed url作为视图模型上的属性公开,然后自定义绑定可以在更新时读取。
自定义绑定非常简单 - 如果我能做到,那么它必须是:)
以下是KnockOut自定义绑定快速入门的链接:http://knockoutjs.com/documentation/custom-bindings.html
答案 2 :(得分:0)
我也有同样的问题,我试图在durandal视图模型和视图绑定在一起后直接在元素上设置css属性。我也认为它不起作用,因为视图在我设置值时没有完全组合。
我想出的最好的方法是在durandal中使用viewAttached生命周期事件,我认为这是durandal viewmodel加载周期中的最后一个事件,然后使用setTimeout进一步延迟属性的设置。
这是一个非常垃圾的解决方法,但它现在正在运作。
var viewAttached = function (view) {
var _this = this;
var picker = new jscolor.color($(view).children('.cp')[0], {
onImmediateChange: function() {
_updateCss.call(_this, this.toString());
}
});
picker.fromString(this.color());
setTimeout(function() {
_updateCss.call(_this, _this.color());
}, 1000);
};
var activate = function (data) {
system.log('activated: ' + this.selectors + ' ' + this.color());
};
var deactivate = function (isClose) {
system.log('deactivated, close:' + isClose);
};
return {
viewAttached: viewAttached,
deactivate: deactivate,
activate: activate,
color: this.color
};
答案 3 :(得分:0)
我在计时方面遇到了类似的问题。在初始页面加载中,在页面上加载局部视图的地方我可以调用viewAttached函数并使用jQuery绑定局部视图中的一些元素。时间按预期工作
但是,如果我导航到新页面,然后返回到初始页面,则相同的viewAttached + jQuery方法无法在页面上找到元素......它们尚未附加到dom。
尽我所能确定(到目前为止),这与entrance.js文件中的过渡效果有关。我正在使用导致对象淡出的默认转换和淡入的新对象。通过消除fadeOutTransition(在entrance.js中将其设置为零),我能够使viewAttached函数实际与其同步部分视图附件。
最好的猜测是,当第一个对象淡出时,传入的对象尚未附加到dom,但无论如何都会触发viewAttached方法。