fix(ivy): host bindings should work if input has same name (#27589)

Previously in Ivy, host bindings did not work if they shared a public name
with an Input because they used the `elementProperty` instruction as is.
This instruction was originally built for inside component templates, so it
would either set a directive input OR a native property. This is the
correct behavior for inside a template, but for host bindings, we always
want the native properties to be set regardless of the presence of an Input.

This change adds an extra argument to `elementProperty` so we can tell it to
ignore directive inputs and only set native properties (if it is in the
context of a host binding).

PR Close #27589
This commit is contained in:
Kara Erickson
2018-12-10 14:51:28 -08:00
committed by Alex Rickabaugh
parent ceb14deb60
commit 452668b581
7 changed files with 103 additions and 33 deletions

View File

@ -691,16 +691,15 @@ function createHostBindingsFunction(
const value = binding.expression.visit(valueConverter);
const bindingExpr = bindingFn(bindingContext, value);
const {bindingName, instruction} = getBindingNameAndInstruction(name);
const {bindingName, instruction, extraParams} = getBindingNameAndInstruction(name);
const instructionParams: o.Expression[] = [
elVarExp, o.literal(bindingName), o.importExpr(R3.bind).callFn([bindingExpr.currValExpr])
];
updateStatements.push(...bindingExpr.stmts);
updateStatements.push(o.importExpr(instruction)
.callFn([
elVarExp,
o.literal(bindingName),
o.importExpr(R3.bind).callFn([bindingExpr.currValExpr]),
])
.toStmt());
updateStatements.push(
o.importExpr(instruction).callFn(instructionParams.concat(extraParams)).toStmt());
}
}
@ -752,8 +751,9 @@ function createStylingStmt(
}
function getBindingNameAndInstruction(bindingName: string):
{bindingName: string, instruction: o.ExternalReference} {
{bindingName: string, instruction: o.ExternalReference, extraParams: o.Expression[]} {
let instruction !: o.ExternalReference;
const extraParams: o.Expression[] = [];
// Check to see if this is an attr binding or a property binding
const attrMatches = bindingName.match(ATTR_REGEX);
@ -762,9 +762,13 @@ function getBindingNameAndInstruction(bindingName: string):
instruction = R3.elementAttribute;
} else {
instruction = R3.elementProperty;
extraParams.push(
o.literal(null), // TODO: This should be a sanitizer fn (FW-785)
o.literal(true) // host bindings must have nativeOnly prop set to true
);
}
return {bindingName, instruction};
return {bindingName, instruction, extraParams};
}
function createHostListeners(