در حال بارگذاری ...

Building Task App Basics0:00

Now, we can also extract component logic when you need to. To demonstrate this, we'll create a simple task app. So we'll start by defining our component logic inline, and then we'll extract it at the end. But yeah, here we'll set up an input here to add a new task. Maybe the placeholder will be go to the market, to give you an idea. Okay, I want to track what the user types in here, so we'll call it newTask, and that will default to an empty string, but then we will use two-way binding. Okay, so now, at all times, I know what you've typed into the input. Next, we'll say, well, when you submit this form, and remember, we want to prevent the default action for the form, so I always need to add that modifier.

Next, we'll say, well, when you submit this form, and remember, we want to prevent the default action for the form, so I always need to add that modifier. Anyways, when you submit it, well, we should add it to maybe a tasks collection, like an array. So let's define that here. This represents all of our tasks, and when you submit the form, we will push the new task. Finally, we just need to display all of your registered tasks. So we'll use a template for that. We will loop over the tasks, so we'll say task, grab the index as well, and our tasks.

So we'll use a template for that. We will loop over the tasks, so we'll say task, grab the index as well, and our tasks array. We'll then set our key, which is always a good practice, and yeah, maybe a list item is fine, and we'll set this equal to the current task. Okay, so this will all be wrapped within a UL, and don't forget, when you're working with Alpine, this is different from something like Vue. Whenever you want to use a loop or a conditional, like XIF, it needs to be on the template tag. So I don't currently have the ability to do X for on a list item. So we'll tweak this in a moment, but real quick, let's set a list disk for all of the

Clearing Input After Submit1:59

Next, we need some spacing below the input. And then finally, after I add a task, well, the input should be cleared. All right, we can do all of those very easily. To start, I'm going to reformat the page, and then on the input, I'll start by saying width full. So take up all of the available space. Next, on the ul, we'll add a little margin above. So that'll give us this, right? But we can't forget to clear the input. So after we submit the form, push the task to the array, and then clear it.

But we can't forget to clear the input. So after we submit the form, push the task to the array, and then clear it. And remember, if we're thinking in a data-driven way, all we have to do is set newTask to an empty string. Alpine will detect that change and then re-render the input. Let's see. Does that work? Yes, it does. Okay. Very simple, but still pretty neat that we can allow for things like this so easily.

Adding Completion Tracking3:09

Okay, so right off the bat, on the main new task input, I noticed we needed a little padding. Next, it might be nice to track if the task was completed. So on our list item, I'm going to add a new checkbox here. And it sounds like I need to bind that to whether the task was completed, but I don't have an object there. Sounds like we need to create one. So when we fill out a new task, I won't push a string to the tasks array. It will now be an object. So the body of the new task will be what the user types in. But then, yeah, we're also going to track whether or not it is completed.

So the body of the new task will be what the user types in. But then, yeah, we're also going to track whether or not it is completed. And of course, for a new task, it's not completed. So we set that to false. Okay, so now this checkbox will only be checked if the task is completed. Okay, next, we'll say, we'll add a span here where we spit out the body of the task. And real quick, let's take a look. There we go. We have our checkboxes. Next, when I complete one, maybe a line should go through the body of the task itself.

We have our checkboxes. Next, when I complete one, maybe a line should go through the body of the task itself. So there are ways to do this, like with Tailwind. I can use the line-through class, and just to show you, that will add a line, just like what we want. But of course, that should be conditional based on whether you check it. So why don't we bind it here, and we'll say, I want this class if the following condition is truthy. And in this case, it would be task.completed. All right, one more time.

And in this case, it would be task.completed. All right, one more time. But if I complete one, now it's checked. All right, and you know what, let's see how we're doing, 15 seconds left, I think that's good enough. So you get the basic idea, you can keep working on that yourself if you'd like. So now, this is fine, I really have no problem with this. But yeah, in real life, you might encounter situations where what you have to do in all of these event handlers, it's too much. You'd rather extract to a file.

Extracting Component Logic5:00

of these event handlers, it's too much. You'd rather extract to a file. And of course, in Alpine, you can do that. Think about it, x-data here is evaluating an object. But what if we evaluated a function that returns an object? Well, of course, we can do that. So maybe something like task.app, and we'll call a function that returns an object. All right, let task.app equal a function that returns an object. And we've already defined that object, right? So I'm going to paste that in, like so.

And we've already defined that object, right? So I'm going to paste that in, like so. And if I come back to Firefox, it's still going to work. So now, yeah, feel free to extract whatever makes sense. In this case, maybe this is getting a little lengthy for your taste, maybe you add a method called submit. All right, let's add it here. Notice our data and our methods can live in the same object. So I can say submit, and I'll paste that in. Okay, so just a couple of things here.

So I can say submit, and I'll paste that in. Okay, so just a couple of things here. Now, because we are within a method, Alpine is not going to wrap any of this code in width so that we can easily access these properties without adding this before it. So make sure you manually add that on. The same is going to be true here. All right, finally, clear it out. So this is what we'd end up with. When the User submits the form, call a method submit, and that method is going to push to the tasks array.

When the user submits the form, call a method submit, and that method is going to push to the tasks array. Okay, so now if I come back, it's still going to work, just like it did before. Okay, so if you want my advice here, this is largely a preference thing. I don't think there's a right or a wrong, but my instinct is to keep things in line as long as I can, and I only extract to a function call when it gets to that point where it feels kind of gross, and I think, okay, we've reached the limits of what I'm going to do in line as an attribute value. So at this point, we're now going to move it to a function. That would be my advice.

Moving Logic to File6:58

So at this point, we're now going to move it to a function. That would be my advice. Let the discomfort guide you to refactor. Of course, you can do this at the bottom of the file, but you're probably going to extract it to a dedicated file. So let's go into my public directory, into JS, and I have an empty app.js file here, and I'll paste this in. Okay, now let's go back to welcome, and at the top or bottom, I will import that, /JS/app.js. So now if I come back to Firefox, all of our logic is in a different file, but we still

resources/js/app.js. So now if I come back to Firefox, all of our logic is in a different file, but we still see the same end result. Great. But next, here's something to be aware of. Let's go back to app.js, and let's say instead you are bundling this up. Maybe you use Webpack, maybe you're using Laravel Mix on top of it for a Laravel app, and let's see, resources.js. Yeah, so let's say I'm going to paste it in here, and then this is going to be compiled with the rest of my CSS or my JavaScript.

Bundlers and Window Scope8:16

Yes, I can reference it, and just as a coincidence, it's compiling to that same file, so it overwrites it. But yeah, you're going to notice if you run it in the browser, it's not going to work anymore. See? Let's see. The console. Task app is not defined. And this is due to the way bundlers work. So what we're going to do is come back to our app.js file, and I'm going to define this

And this is due to the way bundlers work. So what we're going to do is come back to our app.js file, and I'm going to define this on the window. I'm going to be explicit about that. As it turns out, Alpine is going to look on the window for your function there. So anyways, if we, I'm just going to do a watcher here, so we keep an eye on changes and then recompile. But anyways, if I come back and give this a refresh, it should work again. And it does. So the lesson of the day is if you're using a bundler, make sure you declare your Alpine

And it does. So the lesson of the day is if you're using a bundler, make sure you declare your Alpine component logic on the window itself. So further on that note, let's say you have a directory here for your Alpine components. All right. So we will now move that there. And what is this? Just taskApp. And I'll declare it there. Next, if I come back to my entry point, yeah, I could say import components taskApp.

And I'll declare it there. Next, if I come back to my entry point, yeah, I could say import TaskApp from taskApp. And I think this would work. So if I come back to Firefox and refresh, yeah, that's going to do the trick as well. However, don't forget, if instead you're returning a module, which is more traditional, then you would have something like this, export default function. Now from your entry point, you would import TaskApp from that file. But yeah, if you take this approach, just remember you're in the same boat again where it's not being defined on the window. So remember to always take a moment to assign it.

Only extract that component logic when you have a good reason to. And when the discomfort of keeping it all in line almost necessitates the need to extract it.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟