Durandal尝试从viewmodel文件夹访问视图

时间:2014-02-09 17:33:19

标签: javascript knockout.js durandal

我有一个组合绑定,当durandal试图找到它在app/viewmodels而不是app/views

下查看的视图

VM看起来像这样

define(["fields/fieldClosures"], function (fields) {
    var ctor = function(opt) {
        this.value = opt.value;
    };

    return fields.readonly.default = ctor;
});

使用撰写绑定的视图

<div data-name="fields">
    <div data-bind="css: { 'has-error': hasError }" class="form-group">
        <label data-name="label" data-bind="attr: { 'for': id }" class="col-lg-3 control-label"></label>
        <div data-name="field" class="col-lg-9"></div>
    </div>
</div>

data-name="field"通过KO配置库的约定被转换为data-bind =“compose:field”。如果我直接使用标准的compose绑定,我会得到相同的结果

更新 VM \ App \ viewmodels \ form \ fields \ readonly \ text.js

的路径

字段是保存对VM的引用的成员

这是包含字段成员

的VM
define(["fields/fieldClosures",
    "fields/readonly/text", //Need to find a better way to load all view models with requirejs without specifying them all here 
    "fields/readonly/date",
    "fields/readonly/number"], function (fields) {
    function factory(closure, opt) {
        for (var index in closure) {
            var model = closure[index];
            if (model.can && model.can(opt == null ? null : ko.unwrap(opt.value))) {
                return model;
            }
        }

        return closure.default;
    }

    var id = 0;
    var ctor = function(label, value, canEdit, options) {
        this.id = "control-" + id++;
        this.label = label;
        var opt = { value: value, label: label, options: options };
        var closure = canEdit ? fields.editors : fields.readonly;
        var model = factory(closure, opt);

        this.field = new model(opt);

        this.field.id = this.id;
        this.hasError = canEdit ? ko.computed(this.getHasError, this) : null;
    };

    ctor.prototype = {
        getHasError: function() {
            return this.field.value.isValid && !this.field.value.isValid();
        }
    };

    return ctor;
});

为viewLocator启用了useConvention,其他视图正在运行,它只是这个视图无法正确加载。好吧,它不适用于以上述方式加载的任何视图

  1. “fields / readonly / text”
  2. “字段/只读/日期”
  3. “字段/只读/数”
  4. 引用是使用工厂创建的,但是构造函数会注入requirejs,例如normal

    更新

    字段是在开始时添加的路径

    requirejs.config({
        paths: {
            'text': '../Scripts/text',
            'durandal': '../Scripts/durandal',
            'plugins': '../Scripts/durandal/plugins',
            'transitions': '../Scripts/durandal/transitions',
            "fields": "viewmodels/form/fields"
        }
    });
    

1 个答案:

答案 0 :(得分:2)

您是否在useConvention上启用了viewLocator?如果不是,默认情况下,durandal将在与viewModel相同的路径中查找视图。以下是执行翻译的viewLocator代码:

convertModuleIdToViewId: function(moduleId) {
    return moduleId;
}

如果您告诉viewLocator useConvention,它会强制您引用的view / viewModels设置。这是相关的源代码(为简洁起见):

useConvention: function(modulesPath, viewsPath, areasPath) {
    modulesPath = modulesPath || 'viewmodels';
    viewsPath = viewsPath || 'views';

    var reg = new RegExp(escape(modulesPath), 'gi');

    this.convertModuleIdToViewId = function (moduleId) {
        return moduleId.replace(reg, viewsPath);
    };
}

另一种方法是使用您自己的convertModuleIdToViewId实现配置视图定位器,并在应用程序生命周期的早期(例如在应用程序入口点)将其挂起:

var configureViewLocator = function () {
    var viewModelsRegex = /viewmodels/gi;

    viewLocator.convertModuleIdToViewId = function (moduleId) {
        return moduleId.replace(viewModelsRegex, "views");
    };
};

希望有所帮助。