2010-10-12 3 views
9

Я разработал небольшой виджет javscript, чтобы превратить некоторые вложенные блоки <ul> в браузер стиля браузера Windows. Недавно я узнал об объекте буквального шаблон и решил дать ей идти, так что организация моего кода что-то вроде этого:javascript объект литеральный шаблон с несколькими экземплярами

var myExplorer = { 
    init : function(settings) { 
     myExplorer.config = { 
      $wrapper : $('#explorerCategories'), 
      $contentHolder : $j('#categoryContent'), 
      loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />' 
     } 
     // provide for custom configuration via init() 
     if (settings && typeof(settings) == 'object') { 
      $.extend(myExplorer.config, settings); 
     } 

     // some more code... 
    }, 

    createExpanderLink : function() { 
     // more code 
    }, 

    anotherMethod : function() { 
     // etc 
    } 
} 

Тогда в моей странице я создал мой проводник с:

$j(function() { 
    myExplorer.init(); 
} 

Все это прекрасно работает. Проблема в том, что я хочу иметь более одного из этих виджетов стиля браузера на одной странице. Я попытался прохождение в различных условиях:

$j(function() { 
    // first instance 
    myExplorer.init(); 

    //second instance 
    var settings = { 
     $wrapper : $('#explorerCategories2'), 
     $contentHolder : $j('#categoryContent2') 
    } 
    myExplorer.init(settings); 

} 

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

ответ

9

Используйте функцию вместо объектного литерала, чтобы вы могли создавать несколько объектов виджета, используя ключевое слово new.

function myExplorer(settings) { 
    // init code here, this refers to the current object 
    // we're not using a global object like myWindow anymore 
    this.config = { 
     $wrapper : $('#explorerCategories'), 
     $contentHolder : $j('#categoryContent'), 
     .. 
    }; 

    // provide for custom configuration 
    if (settings && typeof(settings) == 'object') { 
     $.extend(this.config, settings); 
    } 

    this.someFunction = function() { 
     .. 
    }; 

    this.otherFunction = function() { 

    }; 
} 

Instantate как многие объекты этого виджета, по мере необходимости, используя,

var foo = new myExplorer({ .. }); 
var bar = new myExplorer({ .. }); 
... 
+0

Простите мое невежество, но правильно ли, что при использовании этого шаблона я должен сначала объявить все внутренние функции перед их использованием в пределах окружающей функции myExplorer. Я просто немного смутился вашим комментарием // init. – benb

2

При вызове $.extend(), как это, он объединяет свойства второго объекта в первый:

$.extend(myExplorer.config, settings); 

Вместо этого создайте новый объект, который является результатом слияния, покидающего первый объект (по умолчанию) нетронутым, как это:

this.settings = $.extend({}, myExplorer.config, settings); 

Что это делает еще объединить переданные объекты в первый, но первый новый объект ({}), поэтому мы не затрагивая либо из других, то просто используйте this.settings (или другое имя, чтобы сделать это абсолютно ясно) внутри вашего объекта.

+0

Спасибо. Я попробовал это, но это не сработало для меня. Хотя он создал новый объект настроек в объекте myExplorer, значения по-прежнему были перезаписаны вторым вызовом myExplorer.init (settings). – benb

+0

@ben - Я даже не смотрел на вашу структуру объекта, у вас есть только один объект, вам нужно пройти совершенно другой маршрут для создания вашего объекта, используя вышеизложенное, ответ Анурага - одна из возможностей, есть много паттернов Вот. –

8

Что об этом?

 
var myExplorer = function(settings) { 

    var o = { 
    init: function() { 
     this.somevalue = settings; 
    }, 

    whatever: function() { 
    } 
    }; 

    o.init(); 

    return o; 
}; 

var exp1 = myExplorer('something'); 
var exp2 = myExplorer('anything'); 

console.log(exp1.somevalue); //something 
console.log(exp2.somevalue); //anything 
4

Используйте следующий код для достижения этой цели, помните о «общественном API» (так, что «внутренняя» функция будет видна «снаружи»):

var myExplorer = function() { 
    var init = function(settings) { 
     var config = { 
      $wrapper : $('#explorerCategories'), 
      $contentHolder : $j('#categoryContent'), 
      loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />' 
     } 
     // provide for custom configuration via init() 
     if (settings && typeof(settings) == 'object') { 
      $.extend(config, settings); 
     } 

     // some more code... 
    }, 

    var createExpanderLink = function() { 
     // more code 
    }, 

    var anotherMethod = function() { 
     // etc 
    } 

    // Public API 
    // return the functions you want to use outside of the current instance 
    return { 
     init : init, 
     createExpanderLink : createExpanderLink, 
     anotherMethod : anotherMethod 
    } 
} 
var firstExplorer = new myExplorer(); 
var secondExplorer = new myExplorer(); 
// etc 
0

Из моего понимания вы пытаясь создать новый экземпляр объекта, который был определен с использованием объектной нотации. Объектные литералы могут быть созданы с использованием метода Object.create. Вот код, который объясняет, как создать экземпляр объекта из нотации литерала объекта.

  var objLiteral = { 
       name:"kanthan", 
       address:'', 
       deliver:function(){ 
        if(this.address){ 
         console.log("Your product has been successfully delivered at "+this.address); 
        } 
        else{ 
         console.log("please enter the address to deliver"); 
        } 
       } 
      }; 
      var cum=Object.create(objLiteral); 
      cum.address="gkm colony"; 
      objLiteral.deliver(); 
      cum.deliver(); 
      var cum1=objLiteral; 
      cum1.address="gkm colony"; 
      objLiteral.deliver(); 
      cum1.deliver(); 
Смежные вопросы