简体   繁体   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?

It was kinda hard to come up with the title for this one, hope it's understandable and makes sense. 很难想出这个标题,希望它是可以理解的并且有意义。

Well , maybe, the difficulty to come up with the title reflects some unnecessary complexity of this situation - if there's a simple way to do this I'd love to know. 好吧,也许,拿出标题的难度反映了这种情况的一些不必要的复杂性-如果有一种简单的方法,我很想知道。

In this sample, there's a Car 'class', from which I can instance objects (Cars). 在此示例中,有一个Car'class',可以从中实例对象(Cars)。 It has a template (an SVG, which is not a car, actually, but who cares), and also public methods, used to modify the template, via jQuery. 它有一个模板(实际上是一个SVG,实际上不是汽车,但在乎谁),还有一个公共方法,用于通过jQuery修改模板。

In the carContainerClick() function, how do I access the Car instance whose template is contained by the currently clicked carContainer element? 在carContainerClick()函数中,如何访问其模板包含在当前单击的carContainer元素中的Car实例?

Sample here 在这里取样

$(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");
  }
};

update 更新

i made a little test with the solutions provided here and turns out it makes almost no difference in performance .. but i like the IIFE one for its simplicity. 我对这里提供的解决方案进行了一些测试 ,结果证明它在性能上几乎没有区别..但是我喜欢IIFE,因为它简单易用。 Sample 样品

You can use an inline function as your event handler that passes car as a parameter... however, because the car declaration is hoisted out of your loop (specifically to the top of the current function), you need to ensure that the event handler captures the right Car instance, and not the last one to pass through the loop. 您可以将内联函数用作将car作为参数传递的事件处理程序...但是,由于car声明是从循环中提升的(特别是在当前函数的顶部),因此需要确保事件处理程序捕获正确的Car实例,而不是最后一个要通过循环的实例。

You can create a closure by using a self invoking function expression that creates a new scope for car that exists within the loop and allows the right car instance to be captured when you set up your handler. 您可以通过创建一个新的范围自调用函数表达式创建一个封闭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);
    })();
  }

Now you can have a function that gets handed the Car instance you need. 现在,您可以拥有一个传递所需的Car实例的函数。

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

Use closure to pass the car instance as an argument to the carContainerClick function. 使用闭包将car实例作为参数传递给carContainerClick函数。

I extracted a new function, cause doing that stuff in a for loop will probably not work (always passing the last car as an argument) 我提取了一个新函数,因为在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) {
    //...
}

Try assigning storing it in a property: 尝试分配将其存储在属性中:

$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");
    }
};

Some notes: 一些注意事项:

  • Don't use $ to get elements inside a loop, it's very slow! 不要使用$来使元素进入循环,这非常慢! Store the result in a variable before the loop instead 将结果存储在循环之前的变量中
  • { class: 'car-container'} may fail on old browsers because class was reserved. { class: 'car-container'}在旧版浏览器上可能会失败,因为class是保留的。 Try 'class' with quotes or addClass method. 尝试使用带引号或addClass方法的'class'
  • To remember what is a DOM element and what is a jQuery wrapper, you can use $ at the beginning of the variable name. 要记住什么是DOM元素和什么是jQuery包装器,可以在变量名的开头使用$

Use jQuery's .data() to attach a reference to the car to the template: 使用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);
}

Then later you can access it from the jQuery object: 然后,您可以从jQuery对象访问它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我将 object 分配给 object 的属性时,该属性会变成 object 吗? 如果是这样,我如何通过第二个访问第一个 object? - When I assign an object to a property of an object, does the property become an object? If so, how do I access the first object via the second one? 如何访问字符串对象的属性? - How do I access the property of an object that is a string? JavaScript:如何访问另一个对象内部的对象原型? - JavaScript: How do I access the prototype of an object inside another object? 如何通过另一个对象访问一个对象? - How do I access an object through another object? 如何访问自身内的对象,另一个对象内的对象? - How do I access an object within itself, within another object? 为什么我必须使用括号注释访问我的 object 属性 - Why do I have to access my object property with the bracket annotation 如何访问在运行时添加到对象的属性? - How do I access a property that I added during runtime to an object? 我如何在另一个函数中访问样式对象 - How can i have an access to style object in another function Handlebar中的访问对象属性包含&#39;。&#39; - access object property in handlebar contains '.' 如何访问每个 JSON 对象的属性? - How do I access a property of each JSON object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM