簡體   English   中英

如何通過另一個包含一個對象的對象訪問一個對象,該對象是我要訪問的對象的屬性?

[英]How do I access an object via another object that contains an object which is a property of the object I want to have access to?

很難想出這個標題,希望它是可以理解的並且有意義。

好吧,也許,拿出標題的難度反映了這種情況的一些不必要的復雜性-如果有一種簡單的方法,我很想知道。

在此示例中,有一個Car'class',可以從中實例對象(Cars)。 它有一個模板(實際上是一個SVG,實際上不是汽車,但在乎誰),還有一個公共方法,用於通過jQuery修改模板。

在carContainerClick()函數中,如何訪問其模板包含在當前單擊的carContainer元素中的Car實例?

在這里取樣

$(function(){

  var cars = [];

  for (var i = 0; i < 2; i++) {

    var carContainer = $('<div/>', { class: 'car-container'});
    var car = new Car();

    cars[i] = car;

    carContainer.on('click', carContainerClick);

    carContainer.append(car.getTemplate());
    $('.container').append(carContainer);
  }

  function carContainerClick() {

    // HERE - how do I access the Car instance whose template is contained by the currently clicked carContainer element?

    cars[0].changeColor();
  }
});

function Car () {
  this.template = $('<svg viewBox="0 0 301 259">    <g class="svg-group"><path class="stick-2" fill-rule="evenodd" clip-rule="evenodd" d="M74.192,27.447c2.589-2.042,4.576-3.188,6.991-5.093c0,0,1.753-1.11,0.416-2.945 c-1.13-1.546-3.242,0.014-3.242,0.014c-4.831,3.804-9.678,7.589-14.491,11.418c-2.335,1.861-4.335,4.009-7.954,3.233 c-2.136-0.458-3.892,1.798-3.913,4.021c-0.02,2.326,1.531,4.107,3.734,4.296c2.353,0.2,4.689-1.183,4.635-3.241    c-0.066-2.415,1.215-3.474,2.981-4.492c1.821-1.049,5.809-3.993,7.21-4.785C71.961,29.082,74.192,27.447,74.192,27.447z"/></g></svg>');
}

Car.prototype = {
  getTemplate: function() {
    return this.template;
  },
  changeColor: function() {
    console.log('changeColor');
    $('.svg-group', this.template).find("path, polygon, circle").attr("fill", "#aff");
  }
};

更新

我對這里提供的解決方案進行了一些測試 ,結果證明它在性能上幾乎沒有區別..但是我喜歡IIFE,因為它簡單易用。 樣品

您可以將內聯函數用作將car作為參數傳遞的事件處理程序...但是,由於car聲明是從循環中提升的(特別是在當前函數的頂部),因此需要確保事件處理程序捕獲正確的Car實例,而不是最后一個要通過循環的實例。

您可以通過創建一個新的范圍自調用函數表達式創建一個封閉car 環路存在,並且允許當您設置處理程序來捕捉正確的汽車實例。

  for (var i = 0; i < 2; i++) {
    (function(){
      var carContainer = $('<div/>', { class: 'car-container'});
      var car = new Car();
      cars[i] = car;
      carContainer.on('click', function(){
        carContainerClick(car);
      });
      carContainer.append(car.getTemplate());
      $('.container').append(carContainer);
    })();
  }

現在,您可以擁有一個傳遞所需的Car實例的函數。

  function carContainerClick(car) {
    car.changeColor();
  }

使用閉包將car實例作為參數傳遞給carContainerClick函數。

我提取了一個新函數,因為在for循環中執行此操作可能無法正常工作(始終將最后一輛車作為參數傳遞)

for (var i = 0; i < 2; i++) {
    var carContainer = $('<div/>', { class: 'car-container'});
    var car = new Car();

    cars[i] = car;

    bindCarContainer(carContainer, car);

    carContainer.append(car.getTemplate());
    $('.container').append(carContainer);
}

function bindCarContainer(carContainer, car) {
    carContainer.on('click', function(event) {
        carContainerClick.call(this, car, event);
    });
}

function carContainerClick(car, event) {
    //...
}

嘗試分配將其存儲在屬性中:

$container = $('.container');
for (var i = 0; i < 2; ++i) {
    var car = new Car(),
        carContainer = $('<div/>').addClass('car-container').prop('car', car);
    carContainer.on('click', carContainerClick);
    carContainer.append(car.getTemplate());
    $container.append(carContainer);
}

function carContainerClick() {
    this.car.changeColor();
}

var $template = $('<svg viewBox="0 0 301 259">    <g class="svg-group"><path class="stick-2" fill-rule="evenodd" clip-rule="evenodd" d="M74.192,27.447c2.589-2.042,4.576-3.188,6.991-5.093c0,0,1.753-1.11,0.416-2.945 c-1.13-1.546-3.242,0.014-3.242,0.014c-4.831,3.804-9.678,7.589-14.491,11.418c-2.335,1.861-4.335,4.009-7.954,3.233 c-2.136-0.458-3.892,1.798-3.913,4.021c-0.02,2.326,1.531,4.107,3.734,4.296c2.353,0.2,4.689-1.183,4.635-3.241    c-0.066-2.415,1.215-3.474,2.981-4.492c1.821-1.049,5.809-3.993,7.21-4.785C71.961,29.082,74.192,27.447,74.192,27.447z"/></g></svg>');

function Car () {
    this.$template = $template.clone();
}

Car.prototype = {
    getTemplate: function() {
        return this.$template;
    },
    changeColor: function() {
        console.log('changeColor');
        $('.svg-group', this.$template).find("path, polygon, circle").attr("fill", "#aff");
    }
};

一些注意事項:

  • 不要使用$來使元素進入循環,這非常慢! 將結果存儲在循環之前的變量中
  • { class: 'car-container'}在舊版瀏覽器上可能會失敗,因為class是保留的。 嘗試使用帶引號或addClass方法的'class'
  • 要記住什么是DOM元素和什么是jQuery包裝器,可以在變量名的開頭使用$

使用jQuery的.data()將對汽車的引用附加到模板:

function Car () {
    this.template = $('<svg viewBox="0 0 301 259">    <g class="svg-group"><path class="stick-2" fill-rule="evenodd" clip-rule="evenodd" d="M74.192,27.447c2.589-2.042,4.576-3.188,6.991-5.093c0,0,1.753-1.11,0.416-2.945 c-1.13-1.546-3.242,0.014-3.242,0.014c-4.831,3.804-9.678,7.589-14.491,11.418c-2.335,1.861-4.335,4.009-7.954,3.233 c-2.136-0.458-3.892,1.798-3.913,4.021c-0.02,2.326,1.531,4.107,3.734,4.296c2.353,0.2,4.689-1.183,4.635-3.241    c-0.066-2.415,1.215-3.474,2.981-4.492c1.821-1.049,5.809-3.993,7.21-4.785C71.961,29.082,74.192,27.447,74.192,27.447z"/></g></svg>');
    this.template.data('car', this);
}

然后,您可以從jQuery對象訪問它:

function carContainerClick() {
    var car = this.data('car');
    car.changeColor();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM