Vue: لا يمكن استخدام `: srcObject.prop` لتعيين الخاصية على قيمة خالية

تم إنشاؤها على ٣ ديسمبر ٢٠١٨  ·  3تعليقات  ·  مصدر: vuejs/vue

إصدار

2.5.17

رابط الاستنساخ

https://codesandbox.io/s/ppyq71wrxj

خطوات التكاثر

(انظر الحد الأدنى من ريبرو)

  1. لديك مكون بـ HTMLMediaElement يربط :srcObject.prop بخاصية بعض البيانات (التي تبدأ كـ null ):
<audio :srcObject.prop="stream">
  1. اضبطه على بعض MediaStream :
this.stream = new MediaStream();
  1. أعده إلى null :
this.stream = null;

ما هو متوقع؟

أتوقع أن يكون audio.srcObject فارغًا

ما الذي يحدث بالفعل؟

يبقى مثل MediaStream وهناك خطأ TypeError في السجل.


لقد لاحظت أنها نجحت بالفعل في محاولتي الأولى لكتابة مثال repro: https://jsfiddle.net/4tnkapxo/1/ (ربما لأن الأمر برمته مضمّن؟)

لست متأكدًا من مدى فائدة هذا ، ولكن بناءً على تتبع المكدس ، فهو مرتبط بهذا الرمز ، الموجود في updateDOMProps :

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

يتم تقييم isUndef(null) أنه صحيح ، ولذا فهو يحاول ضبط الخاصية على '' ، لكن srcObject يحتاج تحديدًا إلى null أو MediaStream

improvement

التعليق الأكثر فائدة

ربما لا ينبغي علينا تطبيق التحويل لربط .prop

ال 3 كومينتر

ربما لا ينبغي علينا تطبيق التحويل لربط .prop

الآن بعد أن نظرت إلى الكود ( updateDOMProps في src / platform / web / runtime / modules / dom-props.js) في السؤال أعتقد أنني أفهم ما يحدث بشكل أفضل قليلاً. حالة الاختبار المرتبطة (في unit / modules / vdom / modules / dom-props.spec.js) تجعل الأمر يبدو وكأنه يحمي من الحذف:

  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('')
  })

... لا توجد طريقة عامة "لحذف" خاصية HTMLEmelent بصرف النظر عن تعيينها إلى أي قيمة عشوائية يحددها الواضع. بهذا المعنى ، فإن التحويل إلى سلسلة فارغة كـ elm[key] = ''; هو في الأساس الأقرب إلى الطريقة القياسية. في حالة وجود علامة <img> ، فإن تعيين الخاصية .src لأي شيء بجانب السلسلة الفارغة يؤدي إلى سلوك بغيض جدًا:

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"

(أنا متأكد من أن هناك سببًا وجيهًا لهذا السلوك وله حالات استخدام مشروعة في كل مكان.)

لذلك في هذا السياق ، تبدو السلسلة الفارغة معقولة كقيمة افتراضية مثل أي سلسلة فارغة / undef. لقد جربت تغيير الشيك isUndef(props[key]) إلى props.hasOwnProperty(key) ، أو حتى مجرد مقارنته مباشرة بـ undefined ... من السهل جدًا القيام بذلك ، لكن لا يبدو ذلك حقًا قابلاً للتطبيق إذا كان المستخدمون يعتمدون على القدرة على حذف خاصية من خلال تعيينها على قيمة خالية ؛ إنه غير متوافق مع الإصدارات السابقة. ويبدو أن مجموعات خصائص / عناصر الغلاف الخاصة في dom-props.js فظيعة للغاية حتى لذكرها.

بعد قولي هذا ، هل أقوم بالكثير من الافتراضات هناك؟ هل هذا الرمز هو مجرد حارس ضد الدعائم المفقودة في vnode الجديد؟ هل كان مؤلف الاختبار يأخذ في الاعتبار خاصية src لأنه سبب الفشل؟ هل من المعقول توقع قيام المستخدمين بتوفير القيمة الصحيحة من بين "" و null و undefined عند "حذف" الدعامة؟

من ناحية أخرى ، أعتقد أنه ليس من المنطقي التحدث عن الحذف عندما يتعلق الأمر بخصائص مرتبطة ... كما في مثال <audio :srcObject.prop="stream"> فإن الخاصية المحسوبة stream يجب أن إرجاع شيئًا ما ، لذلك أفترض أن هناك شيئًا ما باستخدام عناصر vnode الداخلية يتجاوز فهمي والذي يجعل من الممكن استبدال {stream: {some: thing}} بـ {} .

إذا كان الاقتراح أعلاه يبدو جيدًا ، فسأفترض أن hasOwnProperty هو الاختيار الصحيح لإجراء ذلك ، ويجب أن تكون النتيجة elm[key] = '' (كما قلت إنه حذف "قياسي" مثل أي ، وربما الحالة الأكثر شيوعًا للتطبيق) ؛ ربما سأكتب طلب سحب هذا الأسبوع. لكنني لا أريد قضاء الوقت إذا لم يكن التغيير آمنًا.

أعتقد أن هذا تم إصلاحه بواسطة f11449d916a468651d4fd5024c37e3eebbc9941f

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات