2.5.17
https://codesandbox.io/s/ppyq71wrxj
(Voir la reproduction minimale)
HTMLMediaElement
qui lie :srcObject.prop
à une propriété de données (qui commence par null
):<audio :srcObject.prop="stream">
MediaStream
valides :this.stream = new MediaStream();
null
:this.stream = null;
Je m'attends à ce que l'audio.srcObject soit nul
il reste en tant que MediaStream et il y a une TypeError dans le journal.
J'ai remarqué que cela fonctionnait réellement lors de ma première tentative d'écriture de l'exemple de repro : https://jsfiddle.net/4tnkapxo/1/ (probablement parce que tout est en ligne ?)
Je ne sais pas à quel point c'est utile, mais d'après la trace de la pile, il est lié à ce code, trouvé dans updateDOMProps
:
for (key in oldProps) {
if (isUndef(props[key])) {
elm[key] = '';
}
}
isUndef(null)
évalue true, et il essaie donc de définir la prop sur ''
, mais srcObject
spécifiquement besoin qu'elle soit null
ou un MediaStream
peut-être que nous ne devrions pas appliquer de transformation pour les liaisons .prop
Maintenant que j'ai regardé le code ( updateDOMProps
dans src/platforms/web/runtime/modules/dom-props.js) en question je pense comprendre un peu mieux ce qui se passe. Le cas de test associé (dans unit/modules/vdom/modules/dom-props.spec.js) donne l'impression qu'il se prémunit contre la suppression :
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('')
})
... Il n'y a pas de moyen générique de "supprimer" une propriété HTMLEmelent
part la définir sur la valeur arbitraire définie par le setter. En ce sens, la conversion en chaîne vide en tant que elm[key] = '';
est fondamentalement la méthode la plus proche d'une méthode standard. dans le cas d'une balise <img>
, définir la prop .src
sur quelque chose à côté d'une chaîne vide entraîne un comportement assez odieux :
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"
(Je suis sûr qu'il y a une bonne raison à ce comportement et qu'il a des cas d'utilisation légitimes partout.)
Donc, dans ce contexte, une chaîne vide semble être une valeur par défaut aussi raisonnable que n'importe quelle autre pour les accessoires null/undef. J'ai expérimenté en changeant le isUndef(props[key])
en props.hasOwnProperty(key)
, ou même en le comparant directement à undefined
... assez simple à faire, mais cela ne semble pas vraiment viable si les utilisateurs dépendent de la possibilité de supprimer un accessoire en le définissant sur null ; ce n'est pas rétrocompatible. Et les combinaisons de propriétés/éléments de boîtiers spéciaux dans dom-props.js
semblent trop manifestement terribles pour même les mentionner.
Cela dit, est-ce que je fais trop d'hypothèses là-bas? ce code est-il purement une protection contre les accessoires manquants dans le nouveau vnode? l'auteur du test ne considérait-il que la propriété src
parce que c'est ce qui a causé un échec ? est-il raisonnable de s'attendre à ce que les utilisateurs fournissent la valeur correcte parmi ""
, null
et undefined
lors de la "suppression" d'un accessoire ?
D'un autre côté, je suppose que cela n'a pas vraiment de sens de parler de suppression en ce qui concerne les propriétés liées... comme dans l'exemple de <audio :srcObject.prop="stream">
la propriété calculée stream
devra renvoyer quelque chose, donc je suppose qu'il y a quelque chose avec les composants internes de vnode qui dépassent ma compréhension qui permet à {stream: {some: thing}}
d'être remplacé par {}
.
Si la suggestion ci-dessus sonne bien, alors je suppose que hasOwnProperty
est la bonne vérification à faire ici, et le résultat devrait être elm[key] = ''
(comme je l'ai dit, c'est une suppression "standard" aussi bonne que n'importe quelle autre , et probablement le cas le plus couramment applicable); Je vais probablement écrire une pull request cette semaine. Mais je ne veux pas passer du temps si ce n'est pas un changement sûr à faire.
Je pense que cela a été corrigé par f11449d916a468651d4fd5024c37e3eebbc9941f
Commentaire le plus utile
peut-être que nous ne devrions pas appliquer de transformation pour les liaisons
.prop