Vue: tidak dapat menggunakan `:srcObject.prop` untuk menyetel prop ke null

Dibuat pada 3 Des 2018  ·  3Komentar  ·  Sumber: vuejs/vue

Versi: kapan

2.5.17

Tautan reproduksi

https://codesandbox.io/s/ppyq71wrxj

Langkah-langkah untuk mereproduksi

(Lihat repro minimal)

  1. memiliki komponen dengan HTMLMediaElement yang mengikat :srcObject.prop ke beberapa properti data (yang dimulai sebagai null ):
<audio :srcObject.prop="stream">
  1. setel ke beberapa MediaStream valid :
this.stream = new MediaStream();
  1. setel kembali ke null :
this.stream = null;

Apa yang diharapkan?

Saya berharap audio.srcObject menjadi null

Apa yang sebenarnya terjadi?

itu tetap sebagai MediaStream dan ada TypeError di log.


Saya perhatikan bahwa itu benar-benar berfungsi dalam upaya pertama saya untuk menulis contoh repro: https://jsfiddle.net/4tnkapxo/1/ (mungkin karena semuanya inline?)

Saya tidak yakin seberapa membantu ini, tetapi berdasarkan jejak tumpukan itu terkait dengan kode ini, ditemukan di updateDOMProps :

  for (key in oldProps) {
    if (isUndef(props[key])) {
      elm[key] = '';
    }
  }

isUndef(null) mengevaluasi true, jadi ia mencoba mengatur prop ke '' , tetapi srcObject secara khusus membutuhkannya menjadi null atau MediaStream

improvement

Komentar yang paling membantu

mungkin kita seharusnya tidak menerapkan transformasi untuk .prop binding

Semua 3 komentar

mungkin kita seharusnya tidak menerapkan transformasi untuk .prop binding

Sekarang saya telah melihat kode ( updateDOMProps di src/platforms/web/runtime/modules/dom-props.js) yang dimaksud, saya pikir saya sedikit lebih mengerti apa yang terjadi. Kasus uji terkait (dalam unit/modules/vdom/modules/dom-props.spec.js) membuatnya tampak seperti melindungi dari penghapusan:

  it('should remove the elements domProps', () => {
    const vnode1 = new VNode('a', { domProps: { src: 'http://localhost/' }})
    const vnode2 = new VNode('a', { domProps: {}})
    patch(null, vnode1)
    const elm = patch(vnode1, vnode2)
    expect(elm.src).toBe('')
  })

...Tidak ada cara umum untuk "menghapus" properti HTMLEmelent selain menyetelnya ke nilai arbitrer apa pun yang ditentukan oleh setter. Dalam pengertian itu, casting ke string kosong sebagai elm[key] = ''; Pada dasarnya adalah yang paling dekat dengan cara standar. dalam kasus tag <img> , menyetel prop .src ke apa pun selain string kosong menghasilkan beberapa perilaku yang cukup menjengkelkan:

09:48:05.267 const img = document.createElement('img')
09:48:08.948 img.src
09:48:08.953 ""
09:48:14.469 img.src = null
09:48:17.213 img.src
09:48:17.222 "https://localhost:8080/null"

(Saya yakin ada alasan bagus untuk perilaku itu dan ada kasus penggunaan yang sah di mana-mana.)

Jadi dalam konteks itu, string kosong sepertinya sama masuk akalnya dengan default untuk props null/undef. Saya telah bereksperimen dengan mengubah cek isUndef(props[key]) menjadi props.hasOwnProperty(key) , atau bahkan hanya membandingkannya langsung dengan undefined ... cukup mudah dilakukan, tetapi tampaknya tidak layak jika pengguna bergantung pada kemampuan untuk menghapus prop dengan menyetelnya ke null; itu tidak kompatibel ke belakang. Dan kombinasi properti/elemen casing khusus di dom-props.js tampaknya terlalu buruk untuk disebutkan.

Yang mengatakan, apakah saya membuat terlalu banyak asumsi di sana? apakah kode itu murni penjaga terhadap alat peraga yang hilang di vnode baru? apakah penulis pengujian hanya mempertimbangkan properti src karena itulah yang menyebabkan kegagalan? apakah masuk akal untuk mengharapkan bahwa pengguna memberikan nilai yang benar dari antara "" , null dan undefined ketika "menghapus" prop?

Di sisi lain, saya kira tidak masuk akal untuk membicarakan penghapusan ketika menyangkut properti terikat... seperti pada contoh <audio :srcObject.prop="stream"> properti yang dihitung stream harus mengembalikan sesuatu, jadi saya berasumsi ada sesuatu dengan vnode internal yang berada di luar pemahaman saya yang memungkinkan {stream: {some: thing}} diganti dengan {} .

Jika saran di atas terdengar baik-baik saja, maka saya akan menganggap hasOwnProperty adalah pemeriksaan yang tepat untuk dilakukan di sana, dan hasilnya seharusnya elm[key] = '' (seperti yang saya katakan itu sama baiknya dengan penghapusan "standar" apa pun , dan mungkin kasus yang paling umum berlaku); Saya mungkin akan menulis permintaan tarik minggu ini. Tetapi saya tidak ingin menghabiskan waktu jika itu bukan perubahan yang aman untuk dilakukan.

Saya pikir ini telah diperbaiki oleh f11449d916a468651d4fd5024c37e3eebbc9941f

Apakah halaman ini membantu?
0 / 5 - 0 peringkat