3

我正在为 mvc4 使用 Durandal 入门模板。我设置了以下简单视图:

<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');

    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 中。一切正常,显示名称已填充,帖子按预期显示。

当我尝试消除按钮并尝试在创建时加载帖子时,我遇到了麻烦。如果我将插件调用放在激活函数中,我不会得到任何结果。我认为这是因为视图没有完全加载,所以元素不存在。我有两个问题:

  1. 如何延迟插件调用的执行,直到视图完全组成?
  2. 更好的是,如何将插件结果加载到可观察的帖子中,而不是使用查询选择器?我尝试了很多组合,但没有运气

谢谢你的帮助。

4

4 回答 4

4

编辑**以下答案适用于 durandal 1.2。在 durandal 2.0viewAttached中已更改为attached


直接从 durandaljs.com 复制粘贴

“每当 Durandal 编写时,它还会检查您的模型中是否存在名为 的函数viewAttached。如果存在,它将调用该函数并将绑定视图作为参数传递。这允许控制器或演示者直接访问 dom 子树它在注入其父级后的某个时间点绑定到该位置。

注意:如果您已设置cacheViews:truethenviewAttached只会在第一次显示视图时调用,在初始绑定时,因为从技术上讲,视图只附加一次。如果您希望覆盖此行为,请设置alwaysAttachView:true您的组合绑定。”——引自网站


有很多方法可以做到这一点,但这里只是一种快速而肮脏的方法:

<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');
        }
    };
});
于 2013-03-20T00:59:26.593 回答
2

一般来说,我认为避免在视图模型中直接接触 UI 元素是明智的。

一个好的方法是创建一个可以呈现 rss 提要的自定义 KO 绑定。这样,您就可以保证在绑定执行时视图就位。您可能希望将提要 url 作为属性公开在视图模型上,然后自定义绑定可以在更新时读取它。

自定义绑定非常简单 - 如果我能做到,那么它一定是:)

这是 KnockOut 自定义绑定快速入门的链接:http: //knockoutjs.com/documentation/custom-bindings.html

于 2013-03-22T14:30:01.127 回答
0

我在时间方面遇到了类似的问题。在初始页面加载时,页面上正在加载部分视图,我可以调用 viewAttached 函数并使用 jQuery 绑定部分视图中的一些元素。时间按预期工作

但是,如果我导航到新页面,然后返回初始页面,相同的 viewAttached + jQuery 方法无法找到页面上的元素......它们尚未附加到 dom。

尽我所能确定(到目前为止)这与 entry.js 文件中的过渡效果有关。我使用的是默认转换,它导致一个对象淡出,一个新对象淡入。通过消除fadeOutTransition(在entry.js中将其设置为零),我能够让viewAttached函数与部分意见附件。

最好的猜测是,当第一个对象淡出时,传入的对象尚未附加到 dom,但无论如何都会触发 viewAttached 方法。

于 2013-04-12T00:12:22.647 回答
0

我也有同样的问题,我试图在 durandal 视图模型和视图绑定在一起之后直接在元素上设置一个 css 属性。我也认为它不起作用,因为在我设置值时视图没有完全组成。

我想出的最好的方法是在 durandal 中使用 viewAttached 生命周期事件,我认为这是 durandal 视图模型加载周期中的最后一个事件,然后使用 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
    };
于 2013-03-01T16:13:05.647 回答