تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Event-Driven Refactor0:03

Graphical applications are extremely event driven and webpages are no different because we have elements on the page that we want users to interact with. And so therefore our code essentially has to wait for the user to do something. And you're somewhat familiar with this as a php developer because you write code that runs on the server, that server isn't going to execute on its own unless if the user makes a request.

that server isn't going to execute on its own unless if the User makes a request. But it's a little bit more involved in the browser. And our code, at least the game code itself is very procedural. I mean here we essentially run through a loop and that is the driving factor that prompts the User to provide a guess. Whereas within an application, we basically need to wait for the User to submit that guess.

Whereas within an application, we basically need to wait for the user to submit that guess. So we need to start to refactor our code to be more event driven and that's going to force us to make a lot of decisions. Like for example, we have the UI and we have the Game class. Do we want to intermingle those things together? Do we want to keep them separate? And you could make arguments for both cases. I think in the long term it would be better if we kept them.

MVC Roles Overview1:09

And you could make arguments for both cases. I think in the long term it would be better if we kept them separate because that just makes things easier to maintain usually. So if you think about it, we are going to kind of follow the MVC pattern in that our UI is the view, the game that we are playing is the model and the event handler is the controller. So I'm setting up a global click event listener because I want

Click Handler Workflow1:37

So I'm setting up a global click event listener because I want to know when the user clicks on this submitGuess button. Because if we look at the ui, the game will start when the user clicks on the playGame button, but it's going to wait for the user to submit a guess. So when the user submits a guess, we need to first of all check the id of the element that received the click event.

of all check the ID of the element that received the click event. And we essentially need to do three things. We need to get the guess from the user, we need to validate the guests, we need to actually check the guests. And I said we have three things, we actually have four. We need to provide feedback. So let's start with the first thing we need to get our guests. And that is going to be

Reading Guess Input2:21

to get our guests. And that is going to be provided by this input element with an ID of guestsInput. So this is part of the UI and I'm gonna do this. I'm gonna collapse pretty much all the code that we don't need to touch right now just to make things a little bit easier to work with and we can get rid of this createLiElement function. And let's scroll all the way up to the ui. In fact, let's collapse the game for now so that we need

And let's scroll all the way up to the ui. In fact, let's collapse the game for now so that we need to first of all get the elements. We will call it inputGuessElement. We want to call the getById function so that we can get the elements with the ID of guestInput and then we want to get its value. Now we could make this a property, but I think a method would be a better solution because we are, you know, performing an action,

but I think a method would be a better solution because we are, you know, performing an action, we are getting something and you could say, well that's what a get accessor is for and yeah, but I'm going to do a method. So we'll call it getGuess and then we will return the value of inputGuess element. Now you know, in the past we have converted this into a number because input elements always return a string it,

we have converted this into a number because input elements always return a string, it's always there, it's an input element, the user types in the string. So therefore we work with strings. In this case we need to work with a numeric value. So we want to convert that string into a number. And we have been doing that using the number function. However, there are a couple of things about that. First of all, number is going

Using parseInt Conversion3:52

However, there are a couple of things about that. First of all, number is going to return either a numeric value or it's going to return not a number, which is okay, but a numeric value can be an integer or it can be a floating point number. We want to work with only integer. So instead we're going to use a function called parseInt. The idea being that it is going to parse something into an integer value.

The idea being that it is going to parse something into an integer value. But there's a couple of things about this function and I guess it would be easier to show you as opposed to try to just explain it. So parsing does exactly what we expect it to do. It parses a string and it doesn't actually have to be a string. You can pass in a floating point number and it will return the integer for that number.

You can pass in a floating point number and it will return the integer for that number. But we typically pass a string and when that string begins with a number, then it's going to return that number. However, if the string contains any non-numeric characters, it stops parsing that string and then just returns the numbers that it has found. So even if we have some numbers followed by some non-numeric characters

So even if we have some numbers followed by some non-numeric characters and then numbers, again, it's only going to return the first set of numbers. Now if our string begins with non-numeric numbers or non-numeric characters, then it immediately returns not a number. And this is very different from the number function because this actually parses a string and tries to convert it into a numeric value.

because this actually parses a string and tries to convert it into a numeric value. Now there is one other thing about parsing and that is we can pass in what's called erratic or erratics. I don't really know how to pronounce it, but the idea is that we can essentially define what base number or base system that we want to use. Of course, we typically use a base 10 and that's what the parseInt function defaults to used to.

Of course, we typically use a base 10 and that's what the parseInt function defaults to. It didn't, it tried to be smart and parse the number based upon whatever the string was, but they fixed it. It always defaults to base 10. But if we wanted, you know, something like base two, like binary or if we wanted hexadecimal, we can parse a number based upon that rate. Now if we have parseInt, it also kind

we can parse a number based upon that rate. Now if we have parseInt, it also kind of goes without saying that we have parseFloat, which is a little bit different. We don't have to specify rate, but it will take whatever string we pass it and it will attempt to parse that into a floating point number. So when it comes to essentially converting a string into a number, yes we can use the number function,

So when it comes to essentially converting a string into a number, yes we can use the number function, but we typically use parseInt, which is what I'm going to use going forward. So now we are able to get our guests, let's go back down to our event listeners so that we can get the guests, we'll call UI::getGuests, and that is our first step. The next step is to validate the guests. Now we are doing that inside of the play method for our Game class, but you know this is gonna go away.

Now we are doing that inside of the play method for our Game class, but you know this is gonna go away because this was very procedural. So instead we're gonna have to break some of this out and put it inside of the events listener and we will need to put some inside of the checkGuess method. So the first thing that we can get rid of is this prompt because we aren't prompting anymore, the user is going to provide that for us.

because we aren't prompting anymore, the user is going to provide that for us. So we can get rid of that. The next thing is converting the string into a number. We don't really need to do that because we have done that, but here is our validation and we basically want the same thing. I'm gonna cut this out so that we can paste this in down here. So we will validate that,

that we can paste this in down here. So we will validate that, but of course we need to change this. Uh, we don't have minRange and maxRange here, but let's say that we have access to the game object. I don't know how we're gonna do that yet, but, but we'll do that and then we will check if the guess is within range. We also need to make sure that our properties here are correct,

Showing UI Feedback7:51

We also need to make sure that our properties here are correct, but two, this is writing that message to the console and we don't want to do that. Instead we want to provide feedback to the ui. So let's say that we'll have a method called showFeedback. We'll pass in that string and yeah, that will tell the user. So our feedback is actually right here. We have this element here with an id of guestFeedback. So let's add that to our UI object.

We have this element here with an Idea of guest feedback. So let's add that to our UI object. The first thing we need to do is retrieve that. We'll just call it feedbackElement. We will get by that ID so that then we will have the showFeedback method where we will get a result and then we will set feedback, do innerHTML equal to that result. So that's all well and good. Uh, let's see. The third thing that we need to do is check the guess,

Decoupling Game from UI8:44

So that's all well and good. Uh, let's see. The third thing that we need to do is check the guess, which we have a method to do that. We call it checkGuess, but we need to do a little bit more such as manipulate our history. But we also need to check the allowDuplicateGuesses. But this is using the UI and remember I want to get away from that. I want to completely decouple the UI from the game.

and remember I want to get away from that. I want to completely decouple the UI from the game. So basically what we need to do is make this available to the constructor. So let's do that. And this doesn't have to be public, so let's make it a private field so that the object that gets passed to the constructor will have allowed duplicate guesses. We'll give it a default of false so that then we can set this

We'll give it a default of false so that then we can set this allowedDuplicateGuesses equals to duplicateGuesses so that whenever we create the game object, which that was done, uh, here for the submit event, let's go ahead and get that constant UI.allowedDuplicateGuesses so that we can then pass that to our game object right here. So let's go ahead and uncomment this. We will pass in allowDuplicateGuesses.

So let's go ahead and uncommon this. We will pass in, allow duplicate guesses. And you know what, I guess we'll do this. We will set game here and for right now we're gonna make this global. I don't want it to be global, but uh, it's gonna be global. So we create our game variable there. We create the game object. When we start the game, we provide all the information and yeah, that's good enough.

When we start the game, we provide all the information and yeah, that's good enough. Now, so let's collapse that, which means that instead of ui.allowDuplicateGuesses, we check our private field, but we need to move this into the checkGuess method. And of course we do this before we actually start checking the guesses, but this also uses that history. So, uh, we need to make this a property on the object as well. And you know, history is something that the UI is gonna have.

a property on the object as well. And you know, history is something that the UI is gonna have to have access to, so we're gonna need to make this public. So let's go ahead and let's create the history inside of the constructor. We'll just initialize it as an empty array just like we did inside of the play method, but we do need to push in our guess to the history. So let's do that. Uh, right after here, we'll keep the order in which we do

So let's do that. Uh, right after here, we'll keep the order in which we do these things the same except here is where things are gonna get a little bit different because we need to return a result. We don't necessarily need to return true here. And you know, I'm sure we're gonna change this, but I think what I want to do is something like this. We'll have $result equals we'll call checkGuess, passing in the $guess,

We'll have $result equals we'll call checkGuess, passing in the $guess, and then to provide feedback, we will once again call the showFeedback method and we will include the $guess. Then we'll say is, and then we will have the $result. So the $result will be like, is too high or too low, something along that line. Now we're, we're gonna need to do something about checking the history.

Now we're, we're gonna need to do something about checking the history length and the max attempts. We, we will get there. For right now, I just want to get the bulk of this refactored. So here we will return, and in the case of a correct guess we'll say correct so that the final result will be guess is correct. Then here we will return where we say that the guess is too low, and then we will essentially do the same thing here.

Testing and Next Steps12:08

Then here we will return where we say that the guess is too low, and then we will essentially do the same thing here to where we will return that the guess is too high. Of course there's a lot of other things we need to do, but I think as far as the basics are concerned, this is going to be okay. So let's try it out. Let's play a game. We'll just use the easy game. Our first guess will be one we submit it is too high that, that, um, that can't be right,

Our first guess will be one we submit it is too high that, that, um, that can't be right, but you know what, we didn't do secret number. This needs to now be created inside of the constructor. So yeah, that's why our guest was too high because our secret number didn't exist at that time. So let's give this another shot. Let's play the game. Our guest of one will probably be too low. Let's guess five, which is too low. Let's guess eight.

Our guest of one will probably be too low. Let's guess five, which is too low. Let's guess eight. So we know it's either six or seven and it's seven. So at least the functionality is working. There are of course a lot of other things that we need to do. We need to show the history, we need to know when the game is over. And really there's a lot of usability things that we need to address.

And really there's a lot of usability things that we need to address. And we will be doing all of that over the next few episodes.

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