سؤال

لقد قمت ببضع ساعات من البحث الإضافي ، لكن ما زلت لا أستطيع العثور على نمط جيد لما أعتقد أنه مشكلة شائعة.

أنا أعمل على تطبيق .NET MVC2. يتكون تطبيقنا من صفحة رئيسية ثم عدد من المشاهدات الجزئية (صفحات متضمنة) كل واحد من المشاهدات الجزئية يتوافق مع عنصر واجهة مستخدم يتكون من لغة البرمجة هيكل و JS-Jquery أحشاء

بعض من واجهة المستخدم لدينا لها تفاعلات غنية مع بعضها البعض ، لذلك بالطبع نحن نستخدم حدث jQuery يربط شيئًا ما بتأثير هذا:

ملخص البيانات عنصر واجهة مستخدم

$(document).bind("DataUpdated", summaryobject.updateTotals());

أداة التلاعب بالبيانات

$(document).trigger("DataUpdated");

المشكلة التي نواجهها هي أنه عندما يتنقل المستخدم إلى أجزاء من التطبيقات ، تتم إزالة هذه الحاجيات (HTML/DOM) من الصفحة واستبدالها بمجموعة جديدة من المشاهدات الجزئية. عندما يقوم المستخدم بالتنقل مرة أخرى ، يتم إعادة تحميل HTML (التمثيل المرئي) مع الربط jQuery الذي يخلق ارتباطًا مزدوجًا.

حتى الآن تبدو حلولي عرجاء بالنسبة لي.

(1) ارتباط بكائن DOM الربط لـ:

$("#summaryobject").bind("DataUpdated", summaryobject.updateTotals());

المشكلة في ذلك هي أن عنصر واجهة المستخدم المنجزة يجب أن يعرف ما هو دوم bject لشراء: $("#summaryobject") أي نوع من الهزائم الغرض.

(2) إنشاء كائن EventBus إلى المسالك الذي يربط الأحداث والسماح فقط بالالتزام بالأحداث مرة واحدة. المشكلة التي أواجهها هي عند تخزين/ربط الأحداث التي لا يمكنني تتبعها من قام بإنشائها حتى لا أستطيع إلغاء تسجيلها إذا كنت بحاجة إلى .... ربما لم تكن الأحداث غير المسجلة ضرورية.

ما هي الأنماط التي يستخدمها الآخرون لإدارة الأحداث المخصصة؟

هل كانت مفيدة؟

المحلول 4

انتهى بي الأمر القيام بذلك الآن:

تحت كائن Pagemanager الخاص بي كتبت هذه الطريقة

function PageManager() {
    this.eventBusRegistry = [];

    ///<summary>Registers Event if not already bound</summary>
    this.registerForEvent = function (eventName, eventOwner, functionToBind) {
        if (this.eventBusRegistry[eventName + eventOwner] == null) {
            this.eventBusRegistry[eventName + eventOwner] = "BOUND";
            $(document).bind(eventName, functionToBind);
        }
    }
}

لفئة واجهة المستخدم الخاصة بي فعلت هذا.

   ///<summary>Widget</summary>
    function Widget(inWidgetName) {

        //the data you wish to update.
        this.data = {};
        //name of widget
        this.widgetName = inWidgetName;
    }

    Widget.prototype.registerForEvent = function (eventName, functiontoBind) {
       //Session is the instance of PageManager
        Session.registerForEvent(eventName, this.widgetName, functiontoBind);
    };

لأي حالة من القطعة التي تتصل بها registerforevent لربط الأحداث.

هذا بعيد عن الحل الأمثل. سيظل تصميمنا لديه تسرب ذاكرة من حيث أننا لا نلقي تسجيل كائنات JS الخاصة بنا. ومع ذلك ، يتم الكتابة فوق كائناتنا في كل مرة يتم تحميلها بشكل أسوأ ، وهي حالة أن كل كائن في التطبيق يمكن تسجيله مرة واحدة ، حتى لو لم يتم استخدامه.

ومع ذلك ، فإن ربط طريقة لحدث ما يرتبط بكائن المستند الذي لم يتم الكتابة عليه أو المسار. لذلك سوف يمنعنا هذا الرمز من إعادة التوصيل. لا يزال لدينا القليل من الإعداد القذر ولكن يجب تقليل التداعيات.

نصائح أخرى

هناك حلان جيدان لمشكلتك (يمكنني رؤيته).

  1. أزل كل ما تبذلونه bind المكالمات واستبدالها بمكالمة واحدة إلى delegate أو live وإعداد مستمع يستمع إلى الكل من الأحداث التي تحدث في التطبيق الخاص بك وتوجهها إلى الأماكن المناسبة. (بمعنى آخر ، إنشاء وحدة تحكم).

  2. استخدم eventbus الذي يسمح بإلغاء وصف الأحداث وكذلك المشترك. أبسط طريقة رأيتها للقيام بذلك مع eventbus هي بيتر ميشو سيناريو الحدث.


/* 
Extremely loosely coupled custom events
Source: 
http://peter.michaux.ca/articles/anonymous-events-extremely-loose-coupling
*/

EventManager = {};

EventManager.events = {};

EventManager.subscribe = function( event_name, subscriber, method_name ) {
    var event = this.events[event_name];
    if ( ! event ) {
        event = this.events[event_name] = [];
    }
    event.push( { s: subscriber, m: method_name } );
    return this;
};

EventManager.unsubscribe = function( event_name, subscriber ) {
    var event = this.events[event_name];
    if ( ! event ) {
        return;
    }
    for ( var i = event.length - 1; i >= 0; i-- ) {
        if ( event[i].s === subscriber ) {
            event.splice( i, 1 );
        }
    }
    return this;
};

EventManager.unsubscribe_all = function( event_name ) {
    delete this.events[event_name];
    return this;
};

EventManager.fire = function( event_name ) {
    var event = this.events[event_name];
    if ( ! event ) {
        return this;
    }
    for ( var i = event.length - 1; i >= 0; i-- ) {
        subscription = event[i];
        subscription.s[subscription.m].apply( subscription.s, arguments );
    }
    return this;
};

مثال على استخدام هذه الطريقة الثانية هو:

EventManager.subscribe("DataUpdated", summaryobject, "updateTotals");
// ... at some point later on ...
EventManager.fire("DataUpdated");
// Fires `updateTotals` with `this` bound to `summaryobject`

يمكنك تجربة بعض الأشياء ، مثل:

  1. أسماء أنواع الأحداث الخاصة بك. وبهذه الطريقة ، في حين عدم إنشاء ارتباط بين حالتين عرض محددين ، يمكنك إنشاء علاقة معممة بين أنواع المشاهدات. من مثالك أعلاه:

    واجهة مستخدم ملخص البيانات أ

    $(document).bind("DataUpdated.Statistics", summaryobject.updateTotals());
    

    أداة معالجة البيانات أ

    $(document).trigger("DataUpdated.Statistics");
    

    تحقق من الوثائق هنا:http://api.jquery.com/bind/

  2. تفريغ معالجات الأحداث كلما تم تفريغ عنصر واجهة مستخدم أو مجموعة منها ، قبل تحميل DOM / Handlers الجديدة.

هل حاولت استخدام live() طريقة الربط؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top