2014-10-01 5 views
1

Так что я использую $ .extend для объединения нескольких компонентов (объектов). Некоторые из этих компонентов имеют функцию с одним и тем же ключом. Я хочу, чтобы конечный расширенный объект имел тот же самый ключ, но указывал ли он на функцию, которая вызывает все версии функций объединенных компонентов один за другим.jQuery расширяет несколько объектов с одинаковой функцией

Так что бы выглядеть примерно так:

var a = { foo: function() { console.log("a"); } }; 
var b = { foo: function() { console.log("b"); } }; 
var c = {}; // Doesn't have foo 

var d = $.extend({}, a, b, c); 
var e = $.extend({}, a, c); 
var f = $.extend({}, c); 

d.foo(); // Should call function() { console.log("a"); console.log("b"); } 
e.foo(); // Should call function() { console.log("a"); } 
f.foo(); // Should call function() {} 

Есть ли прагматичный способ сделать это? Я хочу сделать это только для определенного набора ключей, поэтому я хотел бы объединить все функции этих конкретных клавиш и позволить упорядочиванию в дополнение перезаписывать что-либо еще.

Надеется, что имеет смысл: S

ответ

1

Примечание

f.foo(); // Should call function() {} 

объект c не кажется, имеет свойство foo. callling f.foo() возвращает TypeError: undefined is not a function. Не определено, требуется ли добавить функцию foo в расширенный объект f или вернуть объект c (пустой объект) из анонимной функции? На рисунке ниже, foo функция не добавлено в расширенный f объект.

JQuery $.Callbacks() используется для добавления функций, имеющих foo свойство в $.each()

Попробуйте

var a = { foo: function() { console.log("a"); } }; 
var b = { foo: function() { console.log("b"); } }; 
var c = {}; // Doesn't have foo 

//d.foo(); 
// Should call function() { console.log("a"); console.log("b"); } 
//e.foo(); 
// Should call function() { console.log("a"); } 
//f.foo(); 
// Should call function() {} 

var callbacks = $.Callbacks(); 
var arr = [], d, e, f; 
$.each([a,b,c], function(k, v, j) { 
    var j = [a,b,c]; 
    // filter objects having `foo` property 
    if (v.hasOwnProperty("foo")) { 
    arr.push([v, v.foo]); 
    if (arr.length > 1) { 
     callbacks.add(arr[0][1], arr[1][1]); 
     // `add` `foo` properties to `callbacks` 
     // `fire` both `callbacks` when `object.foo` called 
     j[k -1].foo = callbacks.fire; 
     d = $.extend({}, j[k - 1]) 
    } else { 
     // `else` extend original data (`fn`, `object`) 
     // contained within object 
     e = $.extend({}, j[k + 1]); 
     f = $.extend({}, j[++k + 1]); 
    } 
    } 
}); 

d.foo(); // `a` , `b` 
e.foo(); // `b` 
console.log(f); // `Object {}` 
f.foo() // `TypeError: undefined is not a function` 

jsfiddle http://jsfiddle.net/guest271314/3k35buc1/

См jQuery.Callbacks()

+0

Спасибо! Я хотел бы иметь возможность вызывать foo на возвращаемом объекте, независимо от того, содержались ли в нем компоненты. Мне нужно будет углубиться в ваш ответ, но, похоже, я мог бы использовать ваше решение, но просто добавить фиктивную функцию foo в случае, если она не существует в v. – Andrew

+0

. Добро пожаловать :) Да. благодаря – guest271314

0

Вот что я закончил с основаны от ответа guest271314 в , toMix - это массив компонентов, которые должны быть смешаны с объектом. Мне действительно не нужны фиктивные функции, которые, как я думал, я мог бы использовать, и в итоге я использовал массив функций вместо $ .Callbacks(), чтобы я мог контролировать порядок, в котором вызываются функции. Мне также нужно было использовать функцию call(), чтобы я мог вызывать функции из правильного объекта this.

this.functionMerge = function(toMix) { 
    var callbacks = {}; 
    var functions = {}; 
    var obj = {}; 
    var keys = [ 
    'componentWillMount', 
    'componentDidMount', 
    'componentWillUpdate', 
    'componentDidUpdate', 
    'componentWillUnmount' 
    ] 

    $.each(keys, function(key, value) { 
    callbacks[value] = []; 
    }); 

    for (i = 0; i < toMix.length; ++i) { 
    $.each(keys, function(key, value) { 
     if (toMix[i].hasOwnProperty(value) && typeof toMix[i][value] == 'function') { 
     callbacks[value].push(toMix[i][value]); 
     } 
    }); 
    $.extend(true, obj, toMix[i]); 
    } 

    $.each(keys, function(key, value) { 
    functions[value] = function() { 
     var that = this; 
     $.each(callbacks[value], function(key, value) { 
     value.call(that); 
     }); 
    }; 
    }); 

    return $.extend(true, obj, functions); 
} 
Смежные вопросы