gpt4 book ai didi

javascript - 以干净的方式扩展主干 View 和继承选项

转载 作者:数据小太阳 更新时间:2023-10-29 05:36:33 25 4
gpt4 key购买 nike

这是我关于 SO 的第一个问题,希望我没有搞砸。我已经检查了关于这个问题的其他主题,但它们没有涵盖我遇到的情况。

我正在 Backbone 之上构建一个库来创建移动应用程序。我将所有组件定义为主干 View 的主要原因是因为我想在滚动时进行内存优化(隐藏内容/从 DOM 中删除内容)。

让我先从最理想的防御开始

定义一个基类供其他组件使用,有一些默认我需要在每个组件上使用的属性和一些方便的方法。

UI.Component = Backbone.View.extend({
viewOptions: ['children'],

children: [],

add: function(child) {
this.children.push(child);
}
});

定义一个具有一些默认属性的组件

UI.Header = UI.Component.extend({
viewOptions: ['titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle'],

titleBarChildren: [],

secondaryBarChildren: [],

title: '',

backButtonTitle: 'Back'
});

制作一个在我的应用程序中使用的默认 header

MyApp.Headers.Default = UI.Header.extend({
backButtonTitle: 'Terug',

titleBarChildren: [
new UI.SegmentedController({
children: [
new UI.Button('Lame example')
]
})
]
});

使用我的导航栏

var homePageNavbar = new MyApp.Header.Default({
title: 'Homepage'
});

现在开始吧

console.log(homePageNavbar);

想象一下我们得到了这个输出

// My properties, all nicely inherited
viewOptions: Array[5] //['children', 'titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle']
children: Array[0],
titleBarChildren: Array[1],
secondaryBarChildren: Array[0],
title: "Homepage",
backButtonTitle: "Terug"

// Some stuff that backbone assigns
$el: jQuery.fn.jQuery.init[1]
cid: "view12"
el: HTMLDivElement
options: Object
__proto__: ctor

这就是我最终想要得到的结果,但这需要一些超出我经验的魔法。

附带说明一下,我曾尝试对所有自定义内容使用“选项”属性,但问题是当我创建多个 View 实例时,选项是“共享的”/互相引用。

所以现在我希望我能通过“viewOptions”方法获得更多运气,然后覆盖 _configure method

最好这一切都在 UI.Component 或其子组件中完成。我不希望此库的用户在其 header 定义 (MyApp.Headers.Default = UI.Header.extend) 中添加一些“样板代码”以扩展选项或其他内容。

现在我必须以某种方式从所有“后代”中获取所有属性。我完全不知道该怎么做。我已经尝试了解 Backbone 幕后发生的事情,但我无法全神贯注。

因此非常感谢完成此操作的提示/技巧,也非常欢迎替代方法或不符合我的确切要求的方法。

编辑 1

看起来我有一些“有点”有用的东西,这是它的样子

我覆盖了 _configure 方法,将选项添加到实例上,注意 this.getDefaultOptions() 作为 _.extend 中的第一个参数

UI.Component = Backbone.View.extend({
_configure: function(options) {
var viewOptions = this.viewOptions;
options = _.extend(this.getDefaultOptions ? this.getDefaultOptions() : {}, this.options || {}, options || {});
for (var i = 0, l = viewOptions.length; i < l; i++) {
var attr = viewOptions[i];
if (options[attr]) this[attr] = options[attr];
}
this.options = options;
}
});

我将这个新方法添加到我的所有组件中,并且没有将“共享”属性放入我的基础对象 (UI.Component) 中,因为我无法很好地发挥它。

UI.Header = UI.Component.extend({

viewOptions: ['children', 'backButtonTitle', 'title'],

getDefaultOptions: function() {
return {
children: []
};
},
});

现在,我使用类似这样的东西来定义我的标题

MyApp.Headers.Default = UI.Header.extend({
options: {
backButtonTitle: 'Terug',
titleBarChildren: [
new UI.SegmentedController({
children: [
new UI.Button('Lame example')
]
})
]
}
});

我会保持现在的状态,看看这个“解决方案”是否存在,并会报告。如果您认为自己有更好的答案,请不要犹豫发布 =)

编辑

这是我最新的方法,使用jQuery的深拷贝,看起来还可以

var UI = {};
var App = {
Headers: {}
};

UI.Component = Backbone.View.extend({
blockDefaults: {
children: []
},

initialize: function(options) {
var combinedDefaultsAndOptions = $.extend(true, {}, this.blockDefaults || {}, this.defaults || {}, this.options || {}, options || {});
_.defaults(this, combinedDefaultsAndOptions);
}
});

UI.Header = UI.Component.extend({
defaults: {
backButton: null,
backButtonTitle: null,
secondaryBarChildren: []
}
});

App.Headers.Default = UI.Header.extend({
options: {
backButtonTitle: "App back",
secondaryBarChildren: ["App child"]
}
});

var header1 = new UI.Header({
backButtonTitle: "Header 1 Back",
secondaryBarChildren: ["Header 1 child"]
});

var header2 = new UI.Header({
backButtonTitle: "Header 2 Back",
secondaryBarChildren: ["Header 2 child"]
});

var header3 = new App.Headers.Default({
});

var header4 = new App.Headers.Default({
backButtonTitle: "Overrided App Back"
});

header1.secondaryBarChildren.push('a child for header 1');

console.log(header1, header2, header3, header4);

最佳答案

我认为您想为您的示例覆盖初始化函数,但您有很多事情要做,所以我不确定;如果关闭,请原谅我。我可能只是在清理我认为您正在尝试做的事情,使其成为一个更“ Backbone ”风格的系统。

像这样从你的基础组件开始:

UI.Component = Backbone.View.extend({
defaults : { 'children' : [] },
initialize : function (options) {
_.defaults(options, this.defaults);
_.keys(this.defaults).forEach(function(key) {
this[key] = this.options[key];
}.bind(this));
Backbone.View.prototype.initialize.call(this, options);
},
add: function(child) {
this.children.push(child);
}
});

然后你可以像这样继续扩展它们:

UI.Header = UI.Component.extend({
defaults : {
'titleBarChildren' : [],
'secondaryBarChildren' : [],
'title' : '',
'backButtonTitle' : 'Back'
},
initialize : function (options) {
_.defaults(options, this.defaults);
_.keys(this.defaults).forEach(function(key) {
this[key] = this.options[key];
}.bind(this));
UI.Component.prototype.initialize.call(this, options);
}
});

这是我在代码中尝试做的事情的细目:

Defaults 创建一个干净地保存所有默认属性的对象

    defaults : { 'children' : [] },

Initialize 覆盖允许您继续在 View 之间传递选项,但每个组件都使用您的 defaults 对象来填补空白。

    initialize : function (options) {
// merges your defaults in with the options passed
_.defaults(options, this.defaults);
// loop through your required defaults for this view
// assigning the attributes to the passed options
_.keys(this.defaults).forEach(function(key) {
this[key] = this.options[key];
}.bind(this));
// Finally pass all your options up the chain of inheritance
UI.Component.prototype.initialize.call(this, options);
},

关于javascript - 以干净的方式扩展主干 View 和继承选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13479571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com