This course has been updated! We now recommend you take the Ember Octane Fundamentals course.
Transcript from the "Exercise 6 Solution, Part 2" Lesson
[00:00:00]
>> [MUSIC]
[00:00:04]
>> Mike North: Any questions?
>> Speaker 2: We could have avoided their change the way that the favorite things work, but I'm wondering if it's possible by moving the handling of adding to [COUGH] units into the components itself. So, that we wouldn't pass the favorite ends and [INAUDIBLE]
>> Mike North: Very good question there.
[00:00:23] Good good point to raise. So because I am a compulsability nerd I am very careful about doing what you just said.
>> Speaker 2: Except I would say that's less compulsive because you're smearing across both.
>> Mike North: So I want my components to be a way of viewing and interacting with state.
[00:00:47] I don't want them to actually be responsible for changing state.
>> Mike North: The idiomatic way of doing this is to have an action in the outside world be responsible for that. And the reason is that as you start having more components and you're passing the same data. It's shared across viewing your repo and maybe you have a side bar with your favorite stuff and it's all bound to the same data, you don't really want to have all of these things being able to independently change it on their own.
[00:01:23]
>> Speaker 3: So the thing is the doesn't seem like the right spot for that either. Unless maybe, okay yeah, okay [INAUDIBLE].
>> Mike North: It's a slightly contrived example but I'm deliberately. We could absolutely inject the service onto this component. But my belief is that you should almost look at the component like you would look at the text input example there.
[00:01:52] Where obviously you don't have data binding with pure HTML but It's just there to provide a means of interacting with the state. And that's really the primary purpose of this, to surface it to the user to give them a means of doing something. But then when it comes to actually changing things, like if we were dealing with records, I wouldn't want a component to actually Persist something on it's own.
[00:02:20]
>> Speaker 4: So, maybe a user question and I'm fine if you really wanna talk with this one more offline, but say you got a component that takes in model and some related models as a property and you wanna keep that... The one way binding scenario. How do you duplicate that was model in the component and then like urge changes you've made back with your model?
[00:02:45] Like there's a built in ember way to do that?
>> Mike North: So you want to establish a one way binding into a component.
>> Speaker 4: So I pass in model I deal with this address model and component.
>> Mike North: Can you give me a concrete example?
>> Speaker 4: I can show you a concrete example can I explain it though.
[00:03:07]
>> Mike North: So when we talk about one way binding the idea is usually that you just want to render something on the screen and you don't expect it to change. That's the typical use case. And you're sort of opting into a cheaper way of establishing data bounding because you don't need two way bounding.
[00:03:27] And I would have to understand exactly what you're trying to do because your question had baked into it. How do I get back in sync? And to me, that says, well, it's probably not one way binding that you want, in this case. It's probably two way binding. And if it is, but I want to be a purist
[00:03:47]
>> Speaker 4: If I can and deal with it even.
>> Mike North: Both tools exist and both have the appropriate use. The major pivot from Ember 1.x to sort of the 2.0 idioms and what we'll see as a new flavor of component comes out which I'll talk about later today, that will be sort of a parallel track to what I've taught you here.
[00:04:10] The idea is you'll have one way bonding by default. You'll have to opt in to two way bonding and the reasoning behind that, is that very often two way bonding is overkill. It's overkill and overly expensive for what you need. In this case I probably don't need to be updating the star count and the repo count I don't need to connect back to the data cuz I'm just rendering it on the screen it's not something that's gonna be changing in the short term so one way of binding would be totally fine to get away with.
[00:04:47] So.
>> Speaker 5: [INAUDIBLE]
>> Mike North: Yeah, so I'll make sure to touch on that when I talk about sort of the future of Ember components as I get into the forward looking part of today.
>> Speaker 6: I'm just curious about best practices are on documenting past in attributes versus internal computer properties.
[00:05:08] Cuz I've been in scenarios before where, somebody has passed in a property which has collided with an internal property name of the component. What's the best way to kinda differentiate between what properties are able to be passed in versus the internal component state?
>> Mike North: I see what you're saying.
[00:05:23] So, that's a very good point there. So if we go back to repos, and please correct me if I'm off track in terms of understanding what you're talking about. In addition to specifying the properties I intend to use, I could also do something like this.
>> Mike North: So, I can pass data into the component, and I'm actually gonna be setting this property's initial value, when the component's instantiated.
[00:05:55] And internally, the component could be using this here. So I typically will just underscore things because that means private typically and you gotta just catch it in a code review. If you see something like this, like that is a sure sign that you probably shouldn't be doing what you're doing.
[00:06:18] So anything that's important to my component's operation. But not necessarily something I want to include in the contract with the outside world, I will indicate via underscoring it that it's private-ish.
>> Speaker 6: Do you know if there's any plans in the works for bringing array prop types? Type of thing where you're actually specifying these properties and these alone can everywhere passed in?
[00:06:46]
>> Mike North: I don't know, if there's plan to do it. There is a way to respond to undefined properties, right, to a property that's not defined yet.
>> Mike North: There's a hook that you can customize there to raise a warning if something happened. And there are also hooks where you can ensure that everything's sort of is in the correct initial state before you sort of spin up and struggling but that's absolutely a valid concern there and from a documentation standpoint I think this is probably the best answer we have today.
[00:07:31]
>> Speaker 7: Couple from online this might be similar to what You're covering this now but when should you use yield versus passing attributes and having the HTML inside the component .hps?
>> Mike North: Good question. Okay. So, covering yield here. So one use of yield is, when you use a component in black form.
[00:07:56] So, in this case, if I did this and had.
>> Mike North: I don't know how to make it reasonable, in this example, here.
>> Mike North: So, you can see that we've actually been able to takes an arbitrary chunk of HTML and handle bars and place it into the component itself.
[00:08:24] And just to convince you guys, this is actually inside. This is our li, right? And so we've actually, we're inside the component and the reason it's been placed there is because yield is up here. So if I move that down this is kind of a similar concept to outlet.
[00:08:40] This is where the content that's passed in via your block goes. So this is one use of yield. Other uses of yield including building like a custom each kind of thing. Where if you were to have something like this, this is item
>> Mike North: and yield the item. Can you had make something like my-list as listItem.
[00:09:15]
>> Mike North: And then do. So essentially you can customize a collection of objects this way if you yield, from within an each that's defined inside your component, you're essentially making that local variable that's inside the scope on a per iteration basis. You're exposing that to the outside world and so you can just define something like this.
[00:09:40] And you end up with an each-ish thing that will render.
>> Mike North: Yep, hasBlock, it's just a way of detecting how your component's being consumed. It's just a property that's available so you can do if hasBlock and then do something.
>> Mike North: So, if you're building an add on and you wanna support in line use and block use.
[00:10:11] And you might have specific things that happen when You need to validate things that are passed in. This is all the stuff that you'll wanna study more deeply. For the most part, what I see is people designing components to be used in a singular way. One Potential difference from that would be something like this.
[00:10:43] Where I could use the block form of linkto instead of the inline form.
>> Mike North: So this is a great example of has block.
>> Mike North: I want to just yield. Right, just spit out whatever's in the block. Otherwise, the name of the repo.
>> Mike North: And then we're just going to delete all the sample stuff.
[00:11:18] So changing the component in this way, like we'll We will still if we use it inline we'll get exactly what we expect. We also have the option of using it in block form
>> Mike North: what did we call it name Name. So this will actually provide a totally equivalent result.
[00:11:47] But now we have the ability to customize it by styling it in some way. And so it's sort of like, if there's a primary piece of text you'll usually have, either the two things right next to each other like passing in text as an attribute or the yield and in this case you can say that if you are in block mode do this otherwise fall back to a default.
[00:12:15] Just remember you only have one yield and even in the W3C web component speck this is a major lacking thing. The fact that projecting content into a component there is not a good story really anywhere for that. So use your yield wisely, you only have one. Anything else you are going to pass in through an attribute.
[00:12:41] Or pass in a view itself. Pass in a component itself and then render the component within the other component. Or do something hacky which will probably break in future versions of Ember.
>> Speaker 4: If you did put two yields in would you get the same content twice or would you get an error?
[00:12:59] Or is that undefined?
>> Mike North: You get the same content twice but Having asked people who are working in this area of Ember, I've been told, don't count on that continuing to work.
>> Speaker 4: Undefined, got it.
>> Mike North: So, it happens to work.
>> Speaker 4: It's implementation specific, but It's not defined by the spec but it's implementation or done a part.
[00:13:24]
>> Mike North: It will always yield the content twice right now. It has to be.
>> Speaker 4: Right.
>> Mike North: With the component.
>> Speaker 4: That's because it's implemented that way but. And to find the philosophical sense maybe.
>> Mike North: Yeah. Exactly. Exactly. All right. Any other questions? Yes.
>> Speaker 7: Yeah, there's one more.
[00:13:38] Are there a list of system actions? I noticed that you're using error some more, but you didn't manually raise it.
>> Mike North: A list of system actions. Error is gonna be handled by the error substate. Loading as it relates to the loading substate.
>> Speaker 10: Maybe they're asking where is that list?
[00:13:59]
>> Mike North: I don't believe there's a comprehensive list. You can look at the documentation for ember.route because that is the object that those actions relate to. I believe those are the only two that are listed currently but that is the page to track for that kind of thing.