JavaScript デザイン パターンを学ぶ Observer pattern_javascript スキル

WBOY
リリース: 2016-05-16 15:19:18
オリジナル
1049 人が閲覧しました

1. 定義

オブザーバー パターン (パブリッシュ/サブスクライブ パターン): オブジェクト間の 1 対多の依存関係を定義します。オブジェクトの状態が変化すると、それに依存するすべてのオブジェクトに通知されます。
JavaScript では、イベント モデルは通常、従来のオブザーバー パターンを置き換えるために使用されます。
利点:

  • (1) は非同期プログラミングで広く使用でき、コールバック関数を渡す代わりに使用できます。
  • (2) は、オブジェクト間のハードコーディングされた通知メカニズムを置き換えることができ、あるオブジェクトが別のオブジェクトのインターフェイスを明示的に呼び出す必要がなくなりました。 2 つのオブジェクトは簡単に分離できます。

2. DOM イベント – オブザーバー モードの典型的な例

document.body に対するユーザーのクリック アクションを監視する必要がありますが、ユーザーがいつクリックするかを予測する方法がありません。
したがって、document.body の click イベントをサブスクライブします。body ノードがクリックされると、body ノードはこのメッセージをサブスクライバーに発行します。

document.body.addEventListener("click", function() {
  console.log(1);
}, false);

// 可以多个订阅者
document.body.addEventListener("click", function() {
  console.log(2);
}, false);

doucment.body.click();

ログイン後にコピー

特定の Web サイトには、ヘッダー、ナビゲーション ナビゲーション、メッセージ リスト、その他のモジュールがあります。これらのモジュールをレンダリングするには、ユーザーのログイン情報を取得する必要があります。
(1) 一般的な文章:

$.ajax({
  url: './login',
  type: 'post',
  contentType: 'application/json',
  dataType:'json',
  success: function(data) {
    if(data.status === "success") {
      // 登录成功,渲染header、nav
      header.setInfo(data.headerInfo);
      nav.setInfo(data.navInfo);
    }
  }
});
ログイン後にコピー

(2) オブザーバーパターンを使うと切り離しが簡単!

$.ajax({
  ...,
  success: function(data) {
    if(data.status === "success") {
      // 登录成功,发布登陆成功消息
      login.trigger("loginsuccess", data);
    }
  }
});

var header = (function() {
  // 监听消息
  login.listen("loginsuccess", function(data){
    header.setInfo(data.headerInfo);
  });
  return {
    setInfo: function(data) {
      console.log("设置header信息");
    }
  };
})();

var nav = (function() {
  login.listen("loginsuccess", function(data){
    nav.setInfo(data.navInfo);
  });
  return {
    setInfo: function(data) {
      console.log("设置nav信息");
    }
  }
})();
ログイン後にコピー

3. ユニバーサルオブザーバーモード

/*
 * 示例:
 * Event.create("namespace1").listen('click', function(a){
 *   console.log(a);
 * });
 * Event.create("namespace1").trigger("click", 1);
 */
var Event = (function() {
  var global = this,
    Event,
    _default = 'default';

  Event = function() {
    var _listen,
      _trigger,
      _remove,
      _slice = Array.prototype.slice,
      _shift = Array.prototype.shift,
      _unshift = Array.prototype.unshift,
      namespaceCache = [],
      _create,
      find,
      each = function( ary, fn) {
        var ret;
        for(var i = 0, l = ary.length; i < l; i++) {
          var n = ary[i];
          ret = fn.call(n, i, n);
        }
        return ret;
      };
    // 订阅
    _listen = function(key, fn, cache) {
      if(!cache[key]) {
        cache[key] = [];
      }
      cache[key].push(fn);
    };
    // 移除订阅
    _remove = function(key, cache, fn) {
      if(cache[key]) {
        if(fn) {
          for(var i = cache[key].length; i >=0; i++) {
            if(cache[key][i] === fn) {
              cache[key].splice(i, 1);
            }
          }
        }else {
          cache[key] = [];
        }
      }
    };
    // 发布
    _trigger = function() {
     var cache = _shift.call(arguments),
       key = _shift.call(arguments),
       args = arguments,
       _self = this,
       ret,
       stack = cache[key];
      if(!stack || !stack.length) {
        return;
      }
      return each(stack, function() {
        return this.apply(_self, args);
      });
    };
    // 创建命名空间
    _create = function(namespace) {
      var namespace = namespace || _default;
      var cache = {},
        offlineStack = [], // 离线事件
        ret = {
          listen: function (key, fn, last) {
            _listen(key, fn, cache);
            if (offlineStack == null) {
              return;
            }
            if (last === 'last') {
              offlineStack.length && offlineStack.pop()();
            } else {
              each(offlineStack, function () {
                this();
              });
            }
            offlineStack = null;
          },

          one: function (key, fn, last) {
            _remove(key, cache);
            this.listen(key, fn, last);
          },

          remove: function(key, fn, last) {
            _remove(key, cache, fn);
          },

          trigger: function() {
            var fn,
              args,
              _self = this;
            _unshift.call(arguments, cache);
            args = arguments;
            fn = function() {
              return _trigger.apply(_self, args);
            };
            if(offlineStack) {
              return offlineStack.push(fn);
            }
            return fn;
          }
        };

        return namespace &#63; (namespaceCache[namespace] &#63; namespaceCache[namespace] : namespaceCache[namespace] = ret) : ret;
      };

    return {
      create: _create,
      one: function(key, fn, last) {
        var event = this.create();
        event.one(key, fn, last);
      },
      remove: function(key, fn) {
        var event = this.create();
        event.remove(key, fn);
      },
      listen: function(key, fn, last) {
        var event = this.create();
        event.listen(key, fn, last);
      },
      trigger: function() {
        var event = this.create();
        event.trigger.apply(this, arguments);
      }
    };
  }();
  return Event;
})();
ログイン後にコピー

この記事が、JavaScript プログラミングを学習する皆さんのお役に立てれば幸いです。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!