แฮนด์บาร์ / หนวด - มีวิธีในการวนลูปผ่านคุณสมบัติของวัตถุหรือไม่?


216

ตามที่ชื่อของคำถามบอกว่ามีหนวด / มือจับวิธีการวนลูปผ่านคุณสมบัติของวัตถุหรือไม่

ดังนั้นด้วย

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
}

ฉันสามารถทำบางสิ่งในแม่แบบเอ็นจิ้นที่จะเทียบเท่าได้หรือไม่

for(var prop in o)
{
    // with say, prop a variable in the template and value the property value
}

?

คำตอบ:


448

การสนับสนุนในตัวตั้งแต่แฮนด์บาร์ 1.0rc1

รองรับการใช้งานฟังก์ชั่นนี้ได้รับการเพิ่มเข้ากับ Handlebars.js ดังนั้นจึงไม่จำเป็นต้องมีผู้ช่วยเหลือภายนอกเพิ่มเติม

วิธีใช้งาน

สำหรับอาร์เรย์:

{{#each myArray}}
    Index: {{@index}} Value = {{this}}
{{/each}}

สำหรับวัตถุ:

{{#each myObject}}
    Key: {{@key}} Value = {{this}}
{{/each}}

โปรดทราบว่าhasOwnPropertyจะมีการระบุคุณสมบัติเฉพาะที่ผ่านการทดสอบเท่านั้น


2
@Rafi: ไม่มีใครสามารถเข้าใจได้โดยที่ไม่รู้โครงสร้างข้อมูลของคุณ
Jon

3
@Rafi: คุณไม่ได้หมายถึง {{this.title}} ใช่ไหม
nevyn

2
@qodeninja: ง่าย: วิธีเดียวกับที่คุณอ้างถึงค่าในตัวอย่างข้างต้น - {{#each this}}มี การเลือกคำศัพท์ของคุณยังทำให้เกิดความสับสน (สิ่งที่ทำให้หนึ่งวัตถุ "ระดับบนสุด" และอีกอย่างไม่อะไรคีย์ "กำหนดไว้ล่วงหน้า" คืออะไร ฯลฯ ) ดังนั้นคุณอาจต้องการทบทวนแนวคิดเหล่านี้อีกครั้ง
Jon

1
ถ้าไม่ผิดพลาดเฉพาะกับ v1.1.0 นี้สามารถใช้ได้ แต่คำตอบที่ดีขอบคุณ
Renars Sirotins

2
คุณจะทำสิ่งนี้ได้เฉพาะรายการที่อนุญาตพิเศษของคุณสมบัติได้อย่างไร
Marco Prins

70

จริงๆแล้วมันค่อนข้างง่ายที่จะติดตั้งเป็นผู้ช่วย:

Handlebars.registerHelper('eachProperty', function(context, options) {
    var ret = "";
    for(var prop in context)
    {
        ret = ret + options.fn({property:prop,value:context[prop]});
    }
    return ret;
});

จากนั้นใช้มันเพื่อ:

{{#eachProperty object}}
    {{property}}: {{value}}<br/>
{{/eachProperty }}

2
ดูดีคุณต้องเพิ่มการตรวจสอบ hasOwnProperty ภายในลูปเพื่อที่คุณจะไม่ทำซ้ำกับคุณสมบัติต้นแบบ?
monkeyboy

ทางออกที่ดี @Ben ในกรณีที่ทุกคนกำลังพยายามใช้สิ่งนี้กับ Ember ดูคำตอบของฉันด้านล่างเพื่อดูวิธีแก้ปัญหาเพื่อให้มันทำงานได้
flynfish

27

แก้ไข: แฮนด์บาร์ตอนนี้มีวิธีการทำสิ่งนี้ให้สำเร็จ; ดูคำตอบที่เลือกด้านบน เมื่อทำงานกับ Mustache ธรรมดาด้านล่างยังคงมีผล

หนวดสามารถวนซ้ำรายการในอาร์เรย์ได้ ดังนั้นฉันขอแนะนำให้สร้างวัตถุข้อมูลแยกต่างหากที่จัดรูปแบบในลักษณะที่หนวดสามารถทำงานกับ:

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
},
mustacheFormattedData = { 'people' : [] };

for (var prop in o){
  if (o.hasOwnProperty(prop)){
    mustacheFormattedData['people'].push({
      'key' : prop,
      'value' : o[prop]
     });
  }
}

ตอนนี้เทมเพลตหนวดของคุณจะเป็นอย่างไร:

{{#people}}
  {{key}} : {{value}}
{{/people}}

ลองดูที่ส่วน "รายการที่ไม่ว่างเปล่า" ที่นี่: https://github.com/janl/mustache.js


1
ลงเอยด้วยการแนะนำของคุณเพราะฉันต้องการส่งผ่านคุณสมบัติย่อยเพิ่มเติม ขอบคุณสำหรับความช่วยเหลือ!
Ben

ขอบคุณมากความคิดของคุณช่วยฉันอีกวันหนึ่งในการมองหาทางเลือก บรรทัดนี้คือคีย์ mustacheFormattedData = {'people': []};
Matt

คุณจะทำสิ่งนี้กับอาร์เรย์ของวัตถุ "o" ได้อย่างไร
red888

4

นี่คือคำตอบของ @ Ben ที่ได้รับการอัปเดตสำหรับใช้กับ Ember ... โปรดทราบว่าคุณต้องใช้Ember.getเพราะบริบทถูกส่งผ่านเป็นสตริง

Ember.Handlebars.registerHelper('eachProperty', function(context, options) {
  var ret = "";
  var newContext = Ember.get(this, context);
  for(var prop in newContext)
  {
    if (newContext.hasOwnProperty(prop)) {
      ret = ret + options.fn({property:prop,value:newContext[prop]});
    }
  }
  return ret;
});

แม่แบบ:

{{#eachProperty object}}
  {{key}}: {{value}}<br/>
{{/eachProperty }}

ขอบคุณ @flynfish บริบทเป็นสตริงใน Ember? ดูเหมือนว่า .. ค่อนข้างแปลก
Ben

ใช่ฉันไม่แน่ใจจริงๆตั้งแต่ฉันยังใหม่กับ Ember และยังคงพยายามหาทางของฉัน
flynfish

1

@ คำตอบของ Amit นั้นดีเพราะมันจะใช้ได้ทั้งใน Mustache และ Handlebars

เท่าที่เป็นโซลูชันสำหรับแฮนด์บาร์เท่านั้นฉันเห็นมาไม่กี่ตัวและฉันชอบตัวeach_with_keyช่วยบล็อกที่https://gist.github.com/1371586ที่สุด

  • ช่วยให้คุณสามารถวนซ้ำตัวอักษรวัตถุโดยไม่ต้องปรับโครงสร้างพวกเขาก่อนและ
  • มันช่วยให้คุณควบคุมสิ่งที่คุณเรียกตัวแปรสำคัญ ด้วยโซลูชั่นอื่น ๆ คุณจะต้องระมัดระวังเกี่ยวกับการใช้คีย์วัตถุที่ชื่อ'key'หรือ'property'อื่น ๆ

หาดี เป็นเพียงการเตือนผู้อ่านรายอื่น: ผู้ช่วย "key_value" ในส่วนสำคัญนี้มีข้อบกพร่องอยู่ในตัว อ่านความคิดเห็นสำหรับวิธีการแก้ไข
sirentian

0

ขอบคุณสำหรับโซลูชันของ Ben กรณีการใช้ของฉันเพื่อแสดงเฉพาะฟิลด์ตามลำดับ

กับวัตถุ

รหัส:

    handlebars.registerHelper('eachToDisplayProperty', function(context, toDisplays, options) {
    var ret = "";
    var toDisplayKeyList = toDisplays.split(",");
    for(var i = 0; i < toDisplayKeyList.length; i++) {
        toDisplayKey = toDisplayKeyList[i];
        if(context[toDisplayKey]) {
            ret = ret + options.fn({
                property : toDisplayKey,
                value : context[toDisplayKey]
            });
        }

    }
    return ret;
});

วัตถุที่มา:

   { locationDesc:"abc", name:"ghi", description:"def", four:"you wont see this"}

แม่แบบ:

{{#eachToDisplayProperty this "locationDesc,description,name"}}
    <div>
        {{property}} --- {{value}}
    </div>
    {{/eachToDisplayProperty}}

เอาท์พุท:

locationDesc --- abc
description --- def
name --- ghi

0

นี่เป็นฟังก์ชันตัวช่วยสำหรับ mustacheJS โดยไม่มีการจัดรูปแบบข้อมูลล่วงหน้าและรับข้อมูลระหว่างการแสดงผล

var data = {
    valueFromMap: function() {
        return function(text, render) {
            // "this" will be an object with map key property
            // text will be color that we have between the mustache-tags
            // in the template
            // render is the function that mustache gives us

            // still need to loop since we have no idea what the key is
            // but there will only be one
            for ( var key in this) {
                if (this.hasOwnProperty(key)) {
                    return render(this[key][text]);
                }
            }
        };
    },

    list: {
        blueHorse: {
            color: 'blue'
        },

        redHorse: {
            color: 'red'
        }
    }
};

แม่แบบ:

{{#list}}
    {{#.}}<span>color: {{#valueFromMap}}color{{/valueFromMap}}</span> <br/>{{/.}}
{{/list}}

ขาออก:

color: blue
color: red

(ลำดับอาจเป็นแบบสุ่ม - เป็นแผนที่) สิ่งนี้อาจมีประโยชน์หากคุณทราบองค์ประกอบแผนที่ที่คุณต้องการ เพียงระวังค่าเท็จ


-1

ฉันใช้1.0.beta.6มือจับรุ่นเก่าฉันคิดว่ามีการเพิ่มฟังก์ชันการทำงานนี้ในช่วง 1.1 - 1.3 ดังนั้นการอัปเดตเป็น 1.3.0 แก้ปัญหาได้นี่คือการใช้งาน:

การใช้งาน:

{{#each object}}
  Key {{@key}} : Value {{this}}
{{/people}}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.