2009-07-17 14 views
6

jqueryの使用を開始したばかりです。セレクタの使用は本当に楽しいものです。イディオムは、オブジェクトツリー(JSONクエリ結果など)をトラバースするのに非常に便利な方法です。私はこのようなオブジェクトがある場合たとえば、:私はチェイニングではないだろうと認識し、5を取得:DOM要素ではなくプレーンなjavascriptオブジェクト用のjqueryセレクタ

var obj = { 'foo': 1, 'bar': 2, 
      'child': { 'baz': [3, 4, 5] } 
      }; 

を私は$(、objの最後の子バズ ')のようなものを書くことができるようにするのが大好きです私はまだ選択演算子が大好きです。誰かがそのような獣が存在するかどうか、または最も簡単な方法は1つを書くことでしょうか?

+0

でループにし、それをjQueryを使って要素をラップすることです-1]; ? –

+0

これは、このおもちゃの例ではうまくいくが、より深い木や大きなオブジェクトではすばやく崩壊する。たとえば、ネットワークパケットを表すツリーを使用するプログラムで作業していますが、到達できないパケットのICMPフレームを取得するために$( 'icmp [code = UNREACHABLE]'、packetlist)を書くことができればと思っています。 – brendan

答えて

5

ここでは、jQuery自体がオブジェクトを処理するための概念実証の実装があります。オブジェクトラッパー(FakeNode)を介して、あなたが使っへのjQueryをだますことができます内蔵のプレーンなJavaScriptオブジェクトのセレクタエンジン(シズル):

function FakeNode(obj, name, parent) { 
    this.obj = obj; 
    this.nodeName = name; 
    this.nodeType = name ? 1 : 9; // element or document 
    this.parentNode = parent; 
} 

FakeNode.prototype = { 
    documentElement: { nodeName: "fake" }, 

    getElementsByTagName: function (tagName) { 
     var nodes = []; 

     for (var p in this.obj) { 
      var node = new FakeNode(this.obj[p], p, this); 

      if (p === tagName) { 
       nodes.push(node); 
      } 

      Array.prototype.push.apply(nodes, 
       node.getElementsByTagName(tagName)); 
     } 

     return nodes; 
    } 
}; 

function $$(sel, context) { 
    return $(sel, new FakeNode(context)); 
} 

および使用方法は、次のようになります。

var obj = { 
    foo: 1, 
    bar: 2, 
    child: { 
     baz: [ 3, 4, 5 ], 
     bar: { 
      bar: 3 
     } 
    } 
}; 

function test(selector) { 
    document.write("Selector: " + selector + "<br>"); 

    $$(selector, obj).each(function() { 
     document.write("- Found: " + this.obj + "<br>"); 
    }); 
} 

test("child baz"); 
test("bar"); 

与えます出力:

 
Selector: child baz 
- Found: 3,4,5 
Selector: bar 
- Found: 2 
- Found: [object Object] 
- Found: 3 

もちろん、もっと複雑なセレクタをサポートするためには、上記よりも多くを実装する必要があります。

ご参考までにjLinqを見ましたか?

+0

これはとてもかわいいです、ありがとう!そして私はjLinqも見ていなかった。 – brendan

+0

これは非常に興味深い答えです。 – ken

0

配列オブジェクトは、あなたが使用できるいくつかの方法があります:まあ、私は純粋なオブジェクトへのアクセスは、jQueryのようなより良く見えることを個人的に言うと思います

first = obj.child.baz.slice(0,1)[0]; 
allExceptFirst = obj.child.baz.slice(1); 
allExceptLast = obj.child.baz.(0,-1); 
+0

ありがとうございます。はい、それは私が今やっていることです。しかしセレクタは私の考えではるかに強力です。なぜなら、興味深い要素を見つけるために歩いている特定のオブジェクトの正確な形状を知る必要がないからです。私はjqueryがhtml.body.table [1] .trをやってくれない理由があると思います... – brendan

0

last = obj.child.baz.slice(-1)[0]; 

他のいくつかの例をクエリ。きちんとしたことの1つはスライシングやその他のフィルタリング技術です。

あなたが本当にオブジェクトアクセスのクエリでプレイしたい場合は、次のようにいくつかの可能性(XPathを考える)のようになります。最後に

var obj = { 
    foo: 1, 
    bar: 2, 
    child: { 
     foo: { 
      baz: [3, {a: 1}, {a: 2, b: 3}]}, 
     bar: { 
      baz: [42, {a: 123}, {a: -1}]}, 
     baz: null}}; 

// Implicitly start in the Global object, unless a context is provided. 
// Keys in JavaScript objects are essentially stored in order (not valid for 
// *all* flavors, but it's close to standard. So you could do slicing on keys.) 

// Selects (does not return them) 
// obj.child.foo.baz[1].a 
// obj.child.foo.baz[2].a 
// obj.child.bar.baz[1].a 
// obj.child.bar.baz[2].a 
// Then performs an aggregate that returns value 125. 
$('obj.child[:2].baz[1:].a').sum() 

// Selects obj.foo, obj.bar, obj.child.foo.baz[0] and obj.child.bar.baz[0] 
$('obj *[typeof(number)]') 

// Selects obj.foo and obj.child.foo 
$('obj foo') 

// Other possible methods: delete(), set(), get() (as an array of values), 
// min(), max(), avg(), merge() etc etc. 

しかし、私はこれは非常に便利であるか表示されません。しかし、それは私が推測するアイデアです)

0

最も簡単なと最も簡単な方法は、あなたがobj.child.baz好きではない理由[obj.child.baz.lengthがあり、各

var obj = { 'foo': 1, 'bar': 2, 
     'child': { 'baz': [3, 4, 5] } 
     }; 

$(obj).each(function(){ 
console.log(this); 
if(this.hasOwnProperty('foo')) 
{ 
    console.log("hey i found " + this.foo); 
} 
}); 
関連する問題